How to renew/extend facebook access tokens with PHP?

Go To StackoverFlow.com

12

Facebook has removed the offline_access token functionality, now tokens have to be renewed whenever the user visits your website to keep them active.

Say someone has already given your website access and you have a token stored for them. What code would you use with Facebook's PHP library to renew that token?

2012-04-05 02:28
by Click Upvote
What do you use tokens for? If you have enough permissions - you don't need to retrieve and store user session tokens, and just use application one - zerkms 2012-04-05 02:31
@zerkms If a user clicks to share a story on his profile on my website, then I'd like to use Ajax to post the story on his FB profile without having to redirect him to facebook each time - Click Upvote 2012-04-05 02:33
then you just need to retrieve publish_stream permission (http://developers.facebook.com/docs/authentication/permissions/#extended_perms, see description ). As long as you have it - you can just post the updates, without user's token - zerkms 2012-04-05 02:36
@zerkms Then what's the point of access tokens, what are they used for now - Click Upvote 2012-04-05 02:37
for example - to authenticate user, and in some cases - to authorize actions (not all actions have correspondent extended permissions - zerkms 2012-04-05 02:38
@zerkms Ok. I'd appreciate if you could still answer the question with the code for renewing the tokens, just so if something I'm trying to do requires authentication, then I'd be able to use the tokens - Click Upvote 2012-04-05 02:39
you cannot refresh them rather than forward user to a facebook. And this is what you know how to do and want to avoid - zerkms 2012-04-05 02:41
ps: "Say someone has already given your website access and you have a token stored for them." --- this is incorrect for facebook. You shouldn't persist user tokens for facebook eve - zerkms 2012-04-05 02:42
@zerkms Do you remember the offline_access token setting? I'm basically trying to replace that - Click Upvote 2012-04-05 02:45
Yep, and you just need to retrieve publish_stream permission and remove user tokens. And it should work ;- - zerkms 2012-04-05 02:58
@zerkms, I get lost in facebook api documentation, so maybe you can quickly answer this. Are you saying that as long as a user authorizes my App for a set of permissions, I don't need to provide any access tokens in my PHP API (get or post) calls to Facebook (within allowed permissions set) if I specify APP ID and APP SECRET? thanks - Alexey Gerasimov 2012-04-08 03:59
@Alexey Gerasimov: exactly. As long as your application has the permission - you don't need anything else, just application token - zerkms 2012-04-08 04:02
@zerkms, thanks. Still confused though. I assume, by app token you mean ones in http://developers.facebook.com/docs/authentication/#applogin. If that's the case, that's what I also meant by needing the token. The token that you get back when the user authorizes your app. I also believe, that's what Click Upvote meant. Maybe not. What if I wanted to (at night) determine which permissions users gave me programatically. You're saying that I don't need provide the accesstoken as FB doc says: https://graph.facebook.com/me/permissions?accesstoken=USERACCESSTOKEN. That's one reason I'd store it - Alexey Gerasimov 2012-04-08 04:32
@Alexey Gerasimov: "You're saying that I don't need provide the access_token" --- I'm not saying that, I'm saying that we don't need personal user token that belongs to a particular user session (that said "permanent" ones) - zerkms 2012-04-08 06:10
@Alexey Gerasimov, If we no need access_token, then I think our application user will need to login every time when he/she want to post data to our created facebook page. If so , our app will need user interaction in every time. I don't want that style - Frank Myat Thu 2012-09-16 23:46
So , I prefer access_token which no need user interaction as long as its expiration date not come - Frank Myat Thu 2012-09-16 23:49
A user token is now always required to publish to a user's Facebook timeline. The "publish_stream" API method that didn't require a user token, no longer exists - Doug S 2015-09-29 02:35


8

You can extend your token the following way:

Original scenario

  • Your app requests permissions from the user
  • You prompt user to log in / grant permissions
  • You get user's token (short-lived one) and exchange via CURL or other means for a 60 day one using grant_type=fb_exchange_token
  • You persist the token

Now you have that token to do what you wish with it for up to 60 days. Up to, because user can change password, de-authorize app, etc and token would become invalid. What you can do to extend the token is EVERY TIME user comes to your page(s), you can check if they are logged in via javascript and if they are, make an ajax call to your server to extend existing token for 60 days from today. You can make as many calls as you want, only the first one is valid. Here's how I do it:

  1. On your page somewhere during load event, add something like:

     FB.getLoginStatus(function (response) {
         if (response.status === 'connected') {
            $.ajax({
                type: "POST",
                async: false,
                url: YOUR_URL,
                dataType: "text",
                data: {token  : response.authResponse.accessToken }
             });
         }
     });
             //rest of jquery ajax call here
    

That will get a new client-side access token for the user and send it to the server

  1. Server can then take that token and exchange it for a 60 day one

    $token_url = "https://graph.facebook.com/oauth/access_token?client_id=".FACEBOOK_CLIENT_ID."&client_secret=".FACEBOOK_SECRET."&grant_type=fb_exchange_token&fb_exchange_token=".$token;
    
    $c = curl_init();
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($c, CURLOPT_URL, $token_url);
    $contents = curl_exec($c);
    $err  = curl_getinfo($c,CURLINFO_HTTP_CODE);
    curl_close($c);
    
    $paramsfb = null;
    parse_str($contents, $paramsfb);        
    

Reference:

https://developers.facebook.com/roadmap/offline-access-removal/

That would only extend the token if the user comes back to your site within 60 days. If not, you will need to prompt for permissions again.

2012-04-08 03:50
by Alexey Gerasimov
Thanks for the answer. Rather than using CURL, isn't there a way to do this using Facebook's own class that they provide - Click Upvote 2012-04-09 02:19
@Click Upvote, probably but I tried to use the FB class and doing api->('/oauth/access_token, 'get', $data) and various permutations but for some reason wasn't getting any data back. Didn't have time to figure out so cheated by doing curl. FB class does CURL too so I am sure it was just some syntax errors on my part. If you figure it out, let me know :) I'd appreciate i - Alexey Gerasimov 2012-04-09 14:13
Facebook PHP SDK (v.3.2.2) has a method to achieve this: Base_Facebook::setExtendedAccessToken( - Lucia 2013-08-15 18:55


1

Updated

Yes @zerkms is right, no access_token is needed if the application has permission.

With this permission, you can publish content to a user's feed at any time. However, please note that Facebook recommends a user-initiated sharing model. Please read the Platform Policies to ensure you understand how to properly use this permission. Note, you do not need to request the publish_stream permission in order to use the Feed Dialog, the Requests Dialog or the Send Dialog.

All extended permissions have similar privileges: https://developers.facebook.com/docs/authentication/permissions/

2012-04-05 07:28
by Adam Pedley
"You will need to get the user to reauthenticate again within 60 days to grab a new token." --- nope. As long as there is publish_stream permitted - you don't need user's tokens ever. Until user deletes the application from apps list - you can post the messages, even after 100 years. So, no, there is no reason to persist any token additionally to application key and secre - zerkms 2012-04-05 09:02
Thanks for correction @zerkm - Adam Pedley 2012-04-05 10:00
just answer my question, how do i renew tokens, this isnt about stream publishin - Click Upvote 2012-04-05 13:50
you renew tokens by getting people to go through the authentication process again. You can't automatically renew tokens, otherwise what is the point of having an expiration date on them - Adam Pedley 2012-04-05 14:19


0

Here's what im currently doing

public function setExtendAccessToken($accessToken = NULL) {

enter code here
    if(!$accessToken) return;

    $graphUrl = 'https://graph.facebook.com/oauth/access_token?client_id='.$facebookAppId.
                '&client_secret='.$facebookSecret.
                '&grant_type=fb_exchange_token&fb_exchange_token='.$accessToken;
    $accessToken = @file_get_contents($graphUrl);
    parse_str($accessToken); //get the access_token param in the string and would be named $access_token
    if(!$access_token) $access_token = $accessToken; //if cannot be extended then just return the access token with 2 hours expiry
    return $access_token;
}
2012-07-06 00:32
by Kugutsumen
Tried this... it does give a different token than what was passed but the issued date and expiration date are the same (using the fb debugger). Just thought others would want to know - ppetree 2013-08-04 22:38
@ppetree maybe you are trying to re-extended the already extended access token? I usually pass fresh access token to this function every time the user authenticates - Kugutsumen 2013-08-05 05:49
Problem is, the extended token supposedly expires in 60 days and I don't want the user to have to reauthenticate... that seems very nonsensical. In my case the user is posting to my site and we're posting to fb and tweeting on their behalf - ppetree 2013-08-09 18:05


0

use Facebook\FacebookSession;
use Facebook\GraphSessionInfo;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;

    FacebookSession::setDefaultApplication('YOURAPPID', 'SECRET');

    $user_accessToken = $_COOKIE['access_token_facebook']

    $session = new FacebookSession($user_accessToken);

    try {
        $session->validate();
    } catch (FacebookRequestException $ex) {
        // When Facebook returns an error
        echo $ex->getMessage();
    } catch (\Exception $ex) {
        // When validation fails or other local issues
        echo $ex->getMessage();
    }
    if ($session) {
        // Exchange token for long token
        $longToken = $session->getExchangeToken();
        // ... your other stuff
    }

Ref: https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens https://developers.facebook.com/docs/facebook-login/access-tokens#extending

2015-04-22 05:42
by Eduardo Chongkan
Ads