Expire server side access token in short period - facebook-graph-api

recently we encountered some strange behavior of server side access token. It expires in very short period (about 15 min). Scenario is following: User login to our page via facebook (server side) and we store access token. Some actions on our page can trigger post /feed. After few feed posts we suddenly started to getting error 400 and error 401.
Error 400 is probably due to limit of number of posts, but after error 401 access token becomes expired.
Every action respond with:
{
"error": {
"message": "Error validating access token: Session has expired at unix
time 1346321603. The current unix time is 1346320983.",
"type": "OAuthException",
"code": 190
"error_subcode": 463
}
Its hard to reproduce this behavior but we reproduced it couple of times on test environment (so we know when access token is created, that user didn't deauthorize app, nor change password).
Any ideas why access token becomes expired?

I double check that "Remove offline_access permission" was enabled on application advanced settings so i can get 60 days server side token.
Not sure why, but all access token have expire "in about hour" reported from access token debugger.
I created new application (also with "Remove offline_access permission") and now i got tokens which expires in 2 months.
Not sure why, but answer was to create new application.

By default facebook assigns a short lived access token. You need to request for long lived token.
Read the doc for how to get it : http://developers.facebook.com/roadmap/offline-access-removal/#extend_token
EDIT:
Previous link doesn't work anymore, use following link
https://developers.facebook.com/docs/roadmap/completed-changes/offline-access-removal/

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.

why oauth 2.0 client id expired automatically?

Execute compute engine
api(GET https://compute.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instances/{resourceId}) with oauth 2.0 client id.
I created an OAuth2.0 client ID and got access_token and refresh_token based on the steps on this site.
Obtaining OAuth 2.0 access tokens
Refreshing an access token (offline access)
I can execute api with access_token which was refreshed.
after 3days, run this step again,
https://developers.google.com/identity/protocols/oauth2/web-server#offline
response was
json
{ "error": "invalid_grant", "error_description": "Token has been expired or revoked." }
why expired refresh_token?
refresh_token
A token that you can use to obtain a new access token. Refresh tokens are valid until the user revokes access. Again, this field is only present in this response if you set the access_type parameter to offline in the initial request to Google's authorization server.
There are a lot of things which can cause a refresh token to expire.
you are using a gmail scope and the user changed their password.
it has not been used in six months.
the user has revoked your access in their google account.
If the user runs your app you get a refresh token, if they run it again you get a different refresh token, you can do this up to 50 times and get new refresh tokens and they will all work after number 50 the first one will expire. Make sure you are always saving the most resent refresh token.
your app is currently in testing and has not been set to published and has not been though the verification process.
Documentation link for expiration

Facebook Messanger. Invalid token

I'm a page admin and trying to debug messanger bot. Recently, I've changed the password and now when I try to reply to myself in messager via API I get an error
{
"error": {
"message": "Error validating access token: The session has been invalidated because the user changed their password or Facebook has changed the session for security reasons.",
"type": "OAuthException",
"code": 190,
"error_subcode": 460
}
}
The thing is I don't have an access token, to begin with, the doc says
To send messages to someone on Messenger, the conversation must be initiated by the user.
It also says
Apps in Development Mode, are restricted to message people that have a role in the app.
I've tried to
Recreate page token
Block/Unblock page and delete conversion
Tried to remove myself from admins, but that's impossible since I'm the only admin
The only option I see left is to remove the app altogether and create a new one, but that doesn't seem like a good solution
This has nothing to do with the fact that the user needs to message your page first, before the bot can respond.
Your bot needs a page token to perform its actions, and according to the error message, the one you have been using, had expired.
So the token you got set in your bot configuration needs to be replaced with a fresh, valid one.

"Provided Authorization Grant is invalid" when using refresh_token WSO2 IS 5.2.0

I recently updated my environment from WSO2 IS 5.0.0 to WSO2 IS 5.2.0. My environment consists of one machine deployed on EC2 AWS instance. I am using MySQL(not the default H2 database). The machine on which the IS is deployed is Windows Server 2012 R2.
I am using the password grant type in order to get access token for particular user and also store the refresh token so that I am able to issue another access token when needed. I am doing the following request in order to get access token:
POST
https://(IS-URL)/oauth2/token?scope=openif&grant_type=password&username=test#abv.bg#localhost.io&password=Asd123##
Configure the appropriate Authorization Basic header
After that I am using the refresh token in order to issue new access tokens. For example:
POST
https://(IS-URL)/oauth2/token?scope=openid&grant_type=refresh_token&refresh_token=
Configure the appropriate Authorization Basic header
After I execute the latest POST call from Postman several times in 2-5 sec interval, after the first 5-7 calls, I start to receive the following error response:
{
"error": "invalid_grant",
"error_description": "Provided Authorization Grant is invalid"
}
I am expecting to receive the new access token and instead I am receiving the mentioned above error. Then I modifiedthe log4j.properties by updating the following lines:
log4j.logger.org.wso2.carbon.identity=DEBUG
log4j.logger.org.wso2.carbon.identity.application=DEBUG
log4j.logger.org.wso2.carbon.identity.mgt=DEBUG
log4j.logger.org.wso2.carbon.identity.oauth2=DEBUG
log4j.logger.org.wso2.carbon.identity.provisioning=DEBUG
log4j.logger.org.wso2.carbon.identity.user.account.association=DEBUG
log4j.logger.org.wso2.carbon.identity.user.profile.mgt=DEBUG
Then I started the IS and tried again the mentioned above scenario and this is what I received in the log file:
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.OAuth2Service} - Access Token request received for Client ID GCFfyPSGkykWG4zQTKoDp8NEvjIa, User ID null, Scope : [openid] and Grant Type : refresh_token
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.token.handlers.clientauth.AbstractClientAuthHandler} - Can authenticate with client ID and Secret. Client ID: GCFfyPSGkykWG4zQTKoDp8NEvjIa
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.token.handlers.clientauth.AbstractClientAuthHandler} - Grant type : refresh_token Strict client validation set to : null
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.util.OAuth2Util} - Client credentials were available in the cache for client id : GCFfyPSGkykWG4zQTKoDp8NEvjIa
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.util.OAuth2Util} - Successfully authenticated the client with client id : GCFfyPSGkykWG4zQTKoDp8NEvjIa
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.token.handlers.grant.RefreshGrantHandler} - Access Token is not in 'ACTIVE' or 'EXPIRED' state for Client with Client Id : GCFfyPSGkykWG4zQTKoDp8NEvjIa
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.token.AccessTokenIssuer} - Invalid Grant provided by the client Id: GCFfyPSGkykWG4zQTKoDp8NEvjIa
[2016-11-15 21:29:18,873] DEBUG {org.wso2.carbon.identity.oauth2.token.AccessTokenIssuer} - OAuth-Error-Code=invalid_grant client-id=GCFfyPSGkykWG4zQTKoDp8NEvjIa grant-type=refresh_token scope=openid
For more information, please take a look at the whole log file:
https://www.dropbox.com/s/ygfc9hrrgxjkzkh/console.log?dl=0
Has someone experienced similar issue and could this be bug in the IS or it is caused by some sort of misconfiguration?
I took a look at Refresh token returns invalid grant type but was not able to find direct answer to the question.
Just want to mention that I tried issuing one request per second and tried this for 5 min interval and was not able to reproduce the issue. It seems it happens when the request frequency is high enough.
Thanks in advance.
As per this code and your logs, the access token is neither in 'ACTIVE' nor 'EXPIRED' state. You can look for that particular token in IDN_OAUTH2_ACCESS_TOKEN table. That will give you a hint about what has gone wrong.
Update:
I analyzed your dataset. The problem is that since you have sent the same token request several times, there are many entries in this tables with TOKEN_STATE=INACTIVE. And also you have 2 entries with the same timestamp (i.e. 2016-11-17 11:40:02) in TIME_CREATED column, which has happened to be the latest among all. So when IS tries to pick the latest token (which ideally should be the ACTIVE one) db server returns 2 tokens. But IS has to pick just one. It can be any of those 2 since the timestamp is the same. So when it picks the INACTIVE one, you should see above error.
Ideally, IS should have handled this properly. But as a solution for you, if you do not keep sending the same request very frequently, you should be able to get rid of the error. Just send a request and wait till the response comes. If it takes a lot of time, that's a different issue to analyze and solve.

How to obtain a long lasting Facebook Access Token?

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.