How to obtain a long lasting Facebook Access Token? - facebook-graph-api

Main objective: How can I get an access token with unlimited validity for a facebook app?
Background information
We have a FB app called MyApp with the following set up:
MyApp is authorized to interact with our facebook app
MyApp has access rights to manage our pages (manage_pages)
MyApp has access to Insights (read_insights)
Our goal is to extract the Insights data automatically, e.g. once every night.
Attempt with oauth generated app token
Get APP_ACCESS_TOKEN belonging to MyAPP
graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials
example of retireved token: 328467452729456598|Wn2Gt69Ofg5ySdOGa3TsP2p4R
Use APP_ACCESS_TOKEN to get PAGE_ACCESS_TOKEN for each page
graph.facebook.com/me/accounts?access_token=APP_ACCESS_TOKEN
Use PAGE_ACCESS_TOKEN to get the page’s Insights data:
graph.facebook.com/YOUR_APP_ID/insights?access_token=PAGE_ACCESS_TOKEN
My problem is that the APP_ACCESS_TOKEN I get from step 1 seems to be missing the user part of the token, resulting in the following error when running step 2:
"message": "An active access token must be used to query information about the current user.",
"type": "OAuthException",
"code": 2500
Attempt with token retrieved from Graph Explorer API token
If I use the APP_ACCESS_TOKEN gained through the Graph API Explorer (https://developers.facebook.com/tools/explorer), I get a token with the user part that is significantly longer.
If I use this token in step 2 and 3, I get correct data, but all tokens are only valid for 2 hours, and subsequently I cannot use this for automated retrieval of insights data.
Attempt with exchanging short lived token for long lived token
Following the steps outlined in this guide: https://developers.facebook.com/roadmap/offline-access-removal/#page_access_token, I tried to exchange a short lived token for a longer lived one.
If I use try to exchange the token obtained from the oauth process, I get the error:
"message": "No user access token specified",
"type": "OAuthException",
"code": 1
If I use the token obtained manually from the Graph explorer in the exchange method, I can get the other steps to work as well, but for how long does this new token last? If the token expires after x days or after the some other event, I would still be faced with the issue of obtaining the initial token programatically (as opposed to manually every from the Graph Explorer).
So does anyone know how I can get a long-lived, automatically retrieved token to solve this?
Thanks!

This shell script attempts to help generate access tokens:
https://github.com/dncohen/fb_token

In step 2, you must use the user's access_token to access the /accounts API endpoint. You cannot use the App Access Token here.
What you should do is:
Get the user's access token from Facebook
Exchange the access_token for a long-lived token
Call /accounts to get a long-live page access token
Access page insights using the long-lived token until it expires
Repeat steps 1-4.

Related

error: invalid_grant , for getting access token using refresh token

After googling we came to know that invalid_grant which means refresh token is invalid.
Link to google oauth doc
We don't have any of these issues mentioned by google. Is this error related to something else rather than a refresh token.
More Info
We have access to read, write spreadsheet and send gmail
We fetch an access token for each request
Any help would be appreciated.
We're already in production and verified by google
Without seeing the full error message that being
Invalid_grant {Message here}
It is hard to help but from my experience is most often caused by one of the following.
Refresh token expire, app not in production.
There are serval reasons why a refresh token can expire the most common one currently is as follows.
A Google Cloud Platform project with an OAuth consent screen configured for an
external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
The fix is to go to google developer console on the consent screen and set your application to production, then your refresh token will stop expiring.
invalid_grant: Invalid JWT
{ “error”: “invalid_grant”, “error_description”: “Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values and use a clock with skew to account for clock differences between systems.” }
Your server’s clock is not in sync with NTP. (Solution: check the server time if its incorrect fix it. )
invalid_grant: Code was already redeemed
Means that you are taking an authentication code that has already been used and trying to get another access token / refresh token for it. Authentication code can only be used once and they do expire so they need to be used quickly.
Invalid_grant: bad request
Normally means that the client id and secrete you are using to refresh the access token. Was not the one that was use to create the refresh token you are using.
Always store most recent refresh token.
Remember to always store the most recent refresh token. You can only have 50 out standing refresh tokens for a single user and the oldest one will expire. Depending upon the language you are using a new refresh token may be returned to you upon a refresh of the access token. Also if you request consent of the user more then once you will get a different refresh token.
User revoked access
If the user revoked your access in their google account, your refresh token will no longer work.
user changed password with gmail scope.
If your refresh token was created with a gmail scope and the user changed their password. your refresh token will be expired.
Links
Oauth2 Rfc docs for invalid_grant error rfc6749
invalid_grant
The provided authorization grant (e.g., authorization
code, resource owner credentials) or refresh token is
invalid, expired, revoked, does not match the redirection
URI used in the authorization request, or was issued to
another client.

Facebook API "This Ads API call requires the user to be admin of the application"

I can successfully pull statistics from the FB API using the temporary access token, however I followed the instructions to generate a token that never expires from this thread.
Long-lasting FB access-token for server to pull FB page info
It does indeed work. But then when trying to using this Page token I get the following error:
Fatal error: Uncaught exception 'FacebookAds\Http\Exception\AuthorizationException' with message '(#272) This Ads API call requires the user to be admin of the application. User XXXXXX not admin or developer for application XXXXXXX.' in
C:\www\projects\dashboard2014\vendor\facebook\php-ads-sdk\src\FacebookAds\Http\Exception\RequestException.php on line 129
However the user is an Admin of the application! I can see it in the application settings. Also I can see the token has the following permissions:
"perms": [
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
In the App settings I also put the Ad account ID in the "Authorized Ad Account IDs" field and this doesn't work still.
If I use the temporary access token from the Graph API Explorer then I am able to pull in data from any campaign in the ad account with no problem, the problems seems to be that this is a Page access token, so there's a slight difference somewhere but I can't seem to work it out?
I don't mind having a different long life access token for every Page rather than just one for the whole account however it's not working. Thanks

How do I give a Facebook App privileges to post to a Facebook Page (I own both)?

I don't understand something important about permissions and how to grant them. I've made a Facebook page, and I've made an app. I would like the app to be able to post to the page.
Below is my code. I'm using the fb_graph ruby gem, btw (https://github.com/nov/fb_graph)
app = FbGraph::Application.new('531508086900000000', :secret => 'd705fda7275125913a10000000000')
token = app.get_access_token
page = FbGraph::Page.new('000000000000000')
note = page.note!( :access_token => token, :subject => 'testing', :message => 'Hey, testing you!')
And this is the error:
FbGraph::Unauthorized: OAuthException :: (#200) Requires extended permission: publish_actions
I've looked everywhere I can think of on both the app and the page settings but can't figure out how to do this. Help appreciated!
You need to grant access via a user access token.
The current token in your case is an application access token.
Use one of the methods listed at https://developers.facebook.com/docs/facebook-login/permissions/v2.1#adding
Specifically https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.1#login
I voted up phwd's answer for the help s/he was to me here and in IRC. But it still wasn't really enough information to make sense of why this is so hard. I've decided to post my current working understanding of how this works. These are just my own notes, so I'm sorry in advance for anything unintelligible.
So, getting the right access tokens is f***ing hard, and here's my current understanding:
In order to get a token that last forever so that my app can post to a page I have to do this:
1. Create a short-lived user access token with the right scope for the app (manage_pages, publish_actions) using the explorer
- page access tokens can be obtained via /me/accounts from the explorer page
- if the user access token that is "live" during the /me/accounts request is short lived then this page access token will be too
- if it is an extended long-lived token the page access token will have no expiry according to https://developers.facebook.com/docs/facebook-login/access-tokens
2. Extend short-lived user access token to a long-lived one via a graph api call, also using exploer (see below)
3. Execute the /me/accounts call to get a page token that doesn't expire
How to get a long lived user access token
oauth/access_token?grant_type=fb_exchange_token&client_id=531------------&client_secret=e005f031ba3d98------------------&fb_exchange_token=CAAHjZA163IbMBAMKSeFTmeV9------------------------------------------------------------------------------------------------------------------------------------------------fonA4P4bPhhdveMLvZBKldEGCB7EvF301wQv1YPrudy5kvI
where
client_id = App Id
&client_secret = App Secret
&fb_exchange_token = short lived user access token via explorer with proper scope
This gives you the following long lived access token
access_token=CAAHjZA163Ib---------------------------------------------------------------------------------------------------------------------------------------------------------------------ehS8g2ZBYU8uZBPmdMay3AAj5tXgAZDZD&expires=5179843
This is an extended user access_token
This token can be used to post to the page it was genrated for.
It can also be used to get a no-expiry page access token when used to issue /me/accounts
from facebook :
Page Access Token
These access tokens are similar to user access tokens, except that they provide permission to APIs that read, write or modify the data belonging to a Facebook Page. To obtain a page access token you need to start by obtaining a user access token and asking for the manage_pages permission. Once you have the user access token you then get the page access token via the Graph API.

Does facebook web app need access token for reading likes of friend status

I'm trying to read likes on my friend's status. It is working fine if i copy the access token from the graph api explorer.
If i use the getAccessToken method. It just returns an array with the id of the status, which was passed by me.
Can anybody help me on how to pass the access tokens to the app.
You may say that why don't you continue with the token copied from graph explorer?
But due to the recent changes offline_access token has been removed, so that the token is expiring for every hour. By the way i'm using graph api with php.
The app needs a user access token if the status is not public – otherwise the API can not detect whether the current user is allowed to see it or not.
Get a long-lived access token: https://developers.facebook.com/roadmap/offline-access-removal/

Facebook Graphi API does not list page accounts in offline mode

My offline Facebook application is trying to retrieve the accounts associated with a specific user id who has previously authorized the application:
https://graph.facebook.com/(userid)/accounts?access_token=(token)
Even though I am passing a valid access token, Facebook returns:
OAuthException: An access token is required to request this resource.
I verified that my access token is correct by querying the likes connection with the same userid and access token:
https://graph.facebook.com/(userid)/likes?access_token=(token)
For this second statement, Facebook returns the expected result.
My application has manage_pages and offline_access permissions. The access token I am using is the access token Facebook returned when the user authorized the application. I don't understand why it works for the likes connection but not for the accounts connection.
Facebook provides different access tokens, some are shorter and some are longer. Without realizing the difference, I had used the shorter ones, created as type='client_cred'. These work fine for retrieving friends lists, lists of fan pages, publishing to stream etc. but apparently they do not work for getting accounts information.
Here is an example of both types of access tokens. Apparently the first one lacks session information (which is the middle part of the second access token).
116122545078207|EyWJJYqrdgQgV1bfueck320z7MM.
116122545078207|2.1vGZASUSFMHeMVgQ_9P60Q__.3600.1272535200-500880518|EyWJJYqrdgQgV1bfueck320z7MM.
If your access token is wrong facebook returns this:
{
"error": {
"type": "OAuthException",
"message": "Error validating access token."
}
}
It seems that the token is not passed to the graph api. Depending on which SDK you use to pass the token, there are different errors that can occur. The PHP SDK for example ignores the token you pass and tries to get the token from the session cookie, which causes errors. Could you clarify how are you making the graph api calls?
I have verified that with a valid token you can get the accounts data. Have you tried pasting this into your browser https://graph.facebook.com/(userid)/accounts?access_token=(token)?