How to extend Facebook User Access Token using PHP SDK? - facebook

I have this code:
$facebook->api("/oauth/access_token?grant_type=fb_exchange_token&client_id=".$facebook->getAppId()."&client_secret=".$facebook->getAppSecret()."&fb_exchange_token=".$user->getFacebookAccessToken());
it does not throw any exception, but it returns null. I am trying to extend a short-lived Facebook User Access Token to be a long-lived Facebook User Access Token. However, after I have generated a new token and calling this request while the new token was still alive, I have waited for a few hours and started a browser where I was not logged in with my facebook account. Then I have logged in with a test user (to the application, not to Facebook), but unfortunately it was directing me to the Facebook login, which means that the Facebook User Access Token was somehow invalidated.
I was working based on the doc found here.
So, can someone enlighten me how should I send the request so Facebook will really extend the token's life cycle? Also, I am not sure how can I determine whether I have successfully extended the life cycle of a Facebook User Access Token. (I am not a Facebook fan, to say the least and I am new to the Facebook API too).
Thanks, guys.
EDIT:
I have read this article and copied the setExtendedAccessToken method into my class with a few modifications to support my logic. Now the code which tries to extend the life cycle of the User Facebook Access Token is as follows:
$facebook->setExtendedAccessToken($user->getFacebookAccessToken());
Now it returns an array of two elements, the token and the expiry date. The expiry date is "5174078". I believe I am on the right track to solve this problem, am I?

Here's what I think you should be doing:
An FB user, logged in, comes to your site and you get a short-lived token for them via the client side flow in the Javascript SDK or a long-lived token via the server-side flow with the PHP or some other SDK (it appears you are doing the first of these already)
If it was a short-lived token, extend it and get a long-lived token via the API call to exchange the token (it appears you're doing this too)
Save long-lived token to your database (not sure if you're doing this)
When the user comes back to your app at some other point, logs in to your app via your own login system, but is not logged in to Facebook, you use the cached token from your database in ->setAccessToken() and then make calls to the Facebook API on their behalf
i think step 4 is your problem; I suspect you're seeing the user is logged-out of Facebook and sending them through the Facebook auth process again instead of having them log into your app via your own login mechanism, and reusing the token you stored before.
This is perfectly fine, but in that case there's no need for you to store the tokens, and you could do this all 'live' and require your users to be still logged into Facebook to fetch a new token 'live' instead of caching the token you obtained on their previous visit to your app.

Just as an FYI cause I've been stumbling around with access token for the last 45 minutes. Via facebook's documentation:
https://developers.facebook.com/docs/roadmap/completed-changes/offline-access-removal/
which seems to be a little dated, I was able to manually extend my existing short lived access token with:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN

Related

Facebook - when does the SDK refresh the auth token?

According to the Facebook docs, mobile SDKs generate long lived tokens which are refreshed once per day when the person using your app makes a request to the Facebook servers. For the javascript SDK, short-lived tokens are generated and are refreshed periodically.
I'm curious as to what is meant by "the person using your app makes a request to the Facebook servers". Which calls specifically will cause the token to be refreshed? Or more importantly, which calls won't? Is it enough to check the login status or is something more active required? What I'm really interested in is keeping the token alive (or getting a new one) without sending the user back through the login flow, or doing anything that's particularly active with Facebooks APIs.
Thanks!
According to Facebook SDK Docu
Once a token expires ("auto" extend of Facebook SDK Token)
At any point, you can generate a new long-lived token by sending the person back to the login flow used by your web app - note that the person will not actually need to login again, they have already authorized your app, so they will immediately redirect back to your app from the login flow with a refreshed token
THERE IS no keep alive functionality in Facebook SDK.
User access tokens come in two forms: short-lived tokens and long-lived tokens. Short-lived tokens usually have a lifetime of about an hour or two, while long-lived tokens usually have a lifetime of about 60 days. You should not depend on these lifetimes remaining the same - the lifetime may change without warning or expire early. See more under handling errors.
long-lived = 60 days
Short-lived = 2 hour
Also according to Facebook SDK Docu
Mobile apps that use Facebook's mobile SDKs get long-lived tokens.
Once you force a user for a new oAuth/login, he will receive a new token. The old one will not expire. You are able to check the loginStatusby FB.getLoginStatus. No need for a keep alive.
The SDK will refresh the access token for you when an actual graph request is made (up to once a day). Any time the token is updated, the AccessTokenTracker will be notified, so you can register a tracker if you want to be notified of updates (e.g. for sending to the server).
If you only make graph requests from your server, then you'll need to handle expiration from there, and either try to extend, or prompt your user to do SSO again to get an updated token.

Facebook: Posting to my own wall through the API

I want my application to post to a single, pre-defined user's wall something like "We just posted a new blog at [URL]" with no client-side interaction.
But every answer I can find on this topic seems to hinge on getting an access token through
https://graph.facebook.com/oauth/access_token
Which gives you some redirect url through which a user has to log in manually.
I've got near zero experience with Facebook. Is it possible to automatically get an access token for a predefined user? Am I doing it wrong? ;)
You can't.
Facebook doesn't give you a way to automatically get an access token for a user. That user needs to log into Facebook and explicitly give your app permission. The best you can get is a long-lived access token that remains valid for up to 60 days.
Getting that token requires a two step process:
1) Logging into Facebook using either the JavaScript API or redirecting the user to a valid Facebook login URL.
2) Retrieving the short-lived access token you got in step 1 for a long-lived access token.
Once you've got that access token, should your post fail, you know you need to re-authenticate the user and get a new long-lived access token. Your user needs to be online and logged into Facebook for this to work, though it can happen without their interaction.

Facebook auth always gives me long-lived access token. I don't want it

I use the Facebook PHP SDK to log in users on my website.
I was experimenting with the "long-lived" access token that expires after 2 months instead of 2 hours. Now I can't get rid of it. It is a problem for me, since it gives me access to the graph API even when the user is logged out of Facebook. I use that to determine if a user is logged in on my site, so it becomes impossible to log out.
I have tried changing the app ID and app secret, as well as deleting my facebook and app cookies, using other accounts, but nothing helps.
How can I get the 2 hour access token back, so I can't use the graph API when the user is not logged in?
The server-side authentication flow will always give you a long-lived access token.
If you want a short-lived one, then you have to use the client-side flow (FB.login from the JavaScript SDK).

How do you renew an expired Facebook access token?

I am working from this reference, and trying to implement the OAuth protocol to allow users to log into my site via Facebook. However, Facebook's documentation is pretty terrible and it unclear in a few key parts.
It says that authorization takes three steps:
User authentication (redirect the user to https://facebook.com/dialog/oauth?client_id=...&redirect_uri=..., and expect the redirect_uri page to be called back with a code). Works great!
App authorization (handled by Facebook, etc). Works great!
App authentication (On the callback page, grab the code you get and call https://graph.facebook.com/oauth/access_token?client_id=...&redirect_uri=...&client_secret=...&code=.... The body of the response will include an access_token we need to do stuff)
I understand that with the access_token, I can call the APIs and such. But, what happens when it expires? I could get a new one, but by this point it will be many HTTP requests later, and I no longer have the code I used to get it in the first place. Do I have to store the code along side the access_token? Or, do I have to tell the user to log in again so I get a new code to get a new access_token?
Or, am I missing a key part here? I don't need an offline_access token, as I will only be polling data in response to user actions .
When the access_token expires, the user will be seen as "logged out" by Facebook. Your app will go through the same process as the first time, but the user may not.
If the user hasn't revoked access to your app, and the user is logged into Facebook at the time, the App Authorization process will take care of itself, with no actions required by the user, and you will receive a new access_token.
If the user hasn't revoked access to your app, but isn't logged into Facebook, they will be presented with a Facebook login at the App Authorization step. They won't be asked to give your app permission again, as Facebook knows that your app id is authorized by that user.
Finally, if the user has revoked access, then they will be presented with the original request for App Authorization, and you'll follow the original flow.
Essentially, you should consider the access_token as volatile, and not bother storing it, but using the access_token you receive as part of the user login process, which is happening behind the scenes all the time, and only involving the user when they log out of Facebook or revoke access to your application.
This is different than Twitter's OAuth with which you can store and re-use it.
From the Facebook documentation linked in your question:
Once the token expires, you will need to re-run the steps above to
generate a new code and access_token, although if the user has already
authorized your app, they will not be prompted to do so again.
When the access_token expires you will need to get a new one by going back through the same steps. The user will have to log in again and you will have to get a new code and in turn, a new access_token.

Do Facebook Oauth 2.0 Access Tokens Expire?

I am playing around with the Oauth 2.0 authorization in Facebook and was wondering if the access tokens Facebook passes out ever expire. If so, is there a way to request a long-life access token?
After digging around a bit, i found this. It seems to be the answer:
Updated (11/April/2018)
The token will expire after about 60 days.
The token will be refreshed once per day, for up to 90 days, when the person using your app makes a request to Facebook's servers.
All access tokens need to be renewed every 90 days with the consent of the person using your app.
Facebook change announce (10/04/2018)
Facebook updated token expiration page (10/04/2018)
offline_access:
Enables your application to perform authorized requests on behalf of the user at any time. By default, most access tokens expire after a short time period to ensure applications only make requests on behalf of the user when the are actively using the application. This permission makes the access token returned by our OAuth endpoint long-lived.
Its a permission value requested.
http://developers.facebook.com/docs/authentication/permissions
UPDATE
offline_access permission has been removed a while ago.
https://developers.facebook.com/docs/roadmap/completed-changes/offline-access-removal/
Try this may be it will help full for you
https://graph.facebook.com/oauth/authorize?
client_id=127605460617602&
scope=offline_access,read_stream,user_photos,user_videos,publish_stream&
redirect_uri=http://www.example.com/
To get lifetime Access Token you have to use scope=offline_access
Meaning of scope=offline_access is that :-
Enables your application to perform authorized requests on behalf of
the user at any time. By default, most access tokens expire after a
short time period to ensure applications only make requests on behalf
of the user when the are actively using the application. This
permission makes the access token returned by our OAuth endpoint
long-lived.
But according to facebook future upgradation the offline_acees functionality will be deprecated for forever from the 3rd October, 2012.
and the user will be given 60 days long-lived access token and before expiration of the access token Facebook will notify or you can get your custom notification functionality fetching the expiration value from the Facebook Api..
Note that Facebook is now deprecating the offline_access permission in favor of tokens for which you can request an "upgrade" to the expiry. I'm just now dealing with this, myself, so I don't have much more to say, but this doc may help:
https://developers.facebook.com/docs/offline-access-deprecation/
I came here with the same question as the OP, but the answers suggesting the use of offline_access are raising red flags for me.
Security-wise, getting offline access to a user's Facebook account is qualitatively different and far more powerful than just using Facebook for single sign on, and should not be used lightly (unless you really need it). When a user grants this permission, "the application" can examine the user's account from anywhere at any time. I put "the application" in quotes because it's actually any tool that has the credentials -- you could script up a whole suite of tools that have nothing to do with the web server that can access whatever info the user has agreed to share to those credentials.
I would not use this feature to work around a short token lifetime; that's not its intended purpose. Indeed, token lifetime itself is a security feature. I'm still looking for details about the proper usage of these tokens (Can I persist them? How do/should I secure them? Does Facebook embed the OAuth 2.0 "refresh token" inside the main one? If not, where is it and/or how do I refresh?), but I'm pretty sure offline_access isn't the right way.
Yes, they do expire. There is an 'expires' value that is passed along with the 'access_token', and from what I can tell it's about 2 hours. I've been searching, but I don't see a way to request a longer expiration time.
since i had the same problem - see the excellent post on this topic from ben biddington, who clarified all this issues with the wrong token and the right type to send for the requests.
http://benbiddington.wordpress.com/2010/04/23/facebook-graph-api-getting-access-tokens/
You can always refresh the user's access token every time the user logs into your site through facebook.
The offline access can't guarantee you get a life-long time access token, the access token changes whenever the user revoke you application access or the user changes his/her password.
Quoted from facebook http://developers.facebook.com/docs/authentication/
Note: If the application has not requested offline_access permission, the access token is time-bounded. Time-bounded access token also get invalidated when the user logs out of Facebook. If the application has obtained offline_access permission from the user, the access token does not have an expiry. However it gets invalidated whenever the user changes his/her password.
Assume you store the user's facebook uid and access token in a users table in your database,every time the user clicks on the "Login with facebook" button, you check the login statususing facebook Javascript API, and then examine the connection status from the response,if the user has connected to your site, you can then update the access token in the table.
Hit this to exchange a short living access token for a long living/non expiring(pages) one:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
log into facebook account and edit your application settings(account -> application setting ->additional permission of the application which use your account). uncheck the permission (Access my data when I'm not using the application(offline_access)). Then face will book issue a new token when you log in to the application.
Basic the facebook token expires about in a hour. But you can using 'exchange' token to get a long-lived token
https://developers.facebook.com/docs/facebook-login/access-tokens
GET /oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={short-lived-token}
This is a fair few years later, but the Facebook Graph API Explorer now has a little info symbol next to the access token that allows you to access the access token tool app, and extend the API token for a couple of months. Might be helpful during development.
check the following things when you interact with facebook graph api.
1) Application connect URL should be the base of your "redirect_uri"
connect URL:- www.x-minds.org/fb/connect/
redirect_uri - www.x-minds.org/fb/connect/redirect
2) Your "redirect_uri" should be same in the both case (when you request for a verification code and request for an access_token)
redirect_uri - www.x-minds.org/fb/connect/redirect
3) you should encode the the argument when you request for an access_token
4) shouldn't pass the argument (type=client_cred) when you request for an access_token. the authorization server will issue a token without session part. we can't use this token with "me" alias in graph api. This token will have length of (40) but a token with session part will have a length of(81).
An access token without session part will work with some cases
eg: -https://graph.facebook.com/?access_token=116122545078207|EyWJJYqrdgQgV1bfueck320z7MM.
But Graph API with "me" alias will work with only token with session part.
I don't know when exactly the tokens expire, but they do, otherwise there wouldn't be an option to give offline permissions.
Anyway, sometimes requiring the user to give offline permissions is an overkill. Depending on your needs, maybe it's enough that the token remains valid as long as the website is opened in the user's browser. For this there may be a simpler solution - relogging the user in periodically using an iframe: facebook auto re-login from cookie php
Worked for me...