Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I renew a Facebook user_access_token if I deal with a lot of AJAX?

Please tell me if I'm understanding correctly. (because I might not be.)

  1. User posts something on my site. (He checked "also post to Facebook".)
  2. Client sends an AJAX POST request to my server, and my server inserts the record in my database.
  3. The server realizes the the facebook user access token is expired, so it sends the response back to the client, while storing the post in a session.
  4. The client does a window.location.replace(facebook_oauth_dialog_url)
  5. Then the user will see a sudden "flash", going to Facebook, then coming back to the website. My server picks up the new access token.
  6. My server checks the session to see what should be posted to Facebook. And then, it uses the new access token to post that to Facebook.

Is it really this tedious? Why can't I renew the app server-side without the user going through the dialog?

My entire site is Backbone.js. That means, it's one big page. I can't jump the user back and forth between Facebook and my website like this.

like image 573
TIMEX Avatar asked Feb 19 '12 01:02

TIMEX


People also ask

How do I renew my Facebook access token?

If the token has expired, your app must send the user through the login flow again to regenerate a new short-lived access token. Make this call from your server, not a client. Your app secret is included in this API call, so you should never make the request client-side.

How do I get Facebook access token that never expires?

In the Access Token Debugger that will open up, click on the 'Extend Access Token' button at the bottom of the page. A new access token should be displayed and the text above it should say that it never expires.

Does Facebook access token expire?

When your app uses Facebook Login to authenticate someone, it receives a User access token. If your app uses one of the Facebook SDKs, this token lasts for about 60 days. However, the SDKs automatically refresh the token whenever the person uses your app, so the tokens expire 60 days after last use.

How do I renew my app on Facebook?

You can find the latest versions of the Facebook apps by visiting your phone's app store (example: App Store, Google Play). From here, you can see what's new with the app and install the latest version.


4 Answers

The idea is to make use of the Facebook JS-SDK methods:

  1. User check the Post To Facebook option
  2. you check if the current user is connected to your app (using FB.getLoginStatus())
  3. if the user is connected, you have two options:
    • post directly using the FB.api method or
    • Send the access_token to your server to complete the post process there
  4. if the user is not connected (or not logged in to Facebook), use the FB.login() method

Here's a quick example (with a Live Demo!) for you to get started:

<!DOCTYPE html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<body>
<div id="fb-root"></div>
<script>
var fbLoaded = false;
window.fbAsyncInit = function() {
    FB.init({
      appId      : 'YOUR_APP_ID', // App ID
      //channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
      status     : true, // check login status
      cookie     : true, // enable cookies to allow the server to access the session
      xfbml      : true  // parse XFBML
    });
    fbLoaded = true;
    // Additional initialization code here

};

function postForm() {
    var msg = document.myForm.msg.value;
    // do form validation here, e.g:
    if(!msg.length) {
        alert("You should enter a message!");
        return false;
    }

    // do we need to post to Facebook?
    if(document.myForm.toFB.checked) {
        // is the library loaded?
        if(!fbLoaded) {
            alert("Facebook JS-SDK is not yet loaded. Please try again later or uncheck Post To Facebook option");
            return false;
        }

        FB.getLoginStatus(function(response) {
            if (response.status === 'connected') {
                var uid = response.authResponse.userID;
                var accessToken = response.authResponse.accessToken;
                /* 
                *  message can be posted to Facebook directly
                *  using the FB.api method or accessToken
                *  can be sent to the server and do the call
                *  from there
                */
                myAjaxCall(msg, accessToken);
            } else {
                // status is either not_authorized or unknown
                FB.login(function(response) {
                    if (response.authResponse) {
                        var accessToken = response.authResponse.accessToken;
                        myAjaxCall(msg, accessToken);
                    } else {
                        alert('User cancelled login or did not fully authorize.');
                    }
                }, {scope: 'publish_stream'});
            }
        });
    } else {
        myAjaxCall(msg);
    }
    return false;
}

function myAjaxCall(m,a) {
    alert("Here you make the ajax call\nMessage: " + m + "\nAccess Token: " + a);
}

  // Load the SDK Asynchronously
  (function(d){
     var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     ref.parentNode.insertBefore(js, ref);
   }(document));
</script>

<form id="myForm" name="myForm" action="post" onSubmit="return postForm()">
<p><label>Your Message:</label><br/><textarea name="msg"></textarea></p>
<p><label>Post to Facebook?</label><input type="checkbox" value="1" name="toFB" /></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
like image 102
ifaour Avatar answered Oct 05 '22 12:10

ifaour


Before posting to the server, call FB.getLoginStatus() on the client to get the latest access token. There is no flash when using this method and no user interaction, as it simply grabs a new access token.

FB.getLoginStatus( function ( response ) {
    if ( response.authResponse ) { 
        var accessToken = response.authResponse.accessToken;
        //post to server
    };
} );
like image 29
ThinkingStiff Avatar answered Oct 05 '22 12:10

ThinkingStiff


I hope you known that if you have publish_stream permission you don't need access token here is documentation for publish_stream and Below is the solution for four scenarios

1.The token expires after expires time (2 hours is the default).
2.The user changes his/her password which invalidates the access token.
3.The user de-authorizes your app.
4.The user logs out of Facebook.

To ensure the best experience for your users, your app needs to be prepared to catch errors for the above scenarios. The following PHP code shows you how to handle these errors and retrieve a new access token.

When you redirect the user to the auth dialog, the user is not prompted for permissions if the user has already authorized your application. Facebook will return you a valid access token without any user facing dialog. However if the user has de-authorized your application then the user will need to re-authorize your application for you to get the access_token.

<?php
$app_id = "YOUR_APP_ID";
$app_secret = "YOUR_APP_SECRET"; 
$my_url = "YOUR_POST_LOGIN_URL";

// known valid access token stored in a database 
$access_token = "YOUR_STORED_ACCESS_TOKEN";

$code = $_REQUEST["code"];

// If we get a code, it means that we have re-authed the user 
//and can get a valid access_token. 
if (isset($code)) {
$token_url="https://graph.facebook.com/oauth/access_token?client_id="
  . $app_id . "&redirect_uri=" . urlencode($my_url) 
  . "&client_secret=" . $app_secret 
  . "&code=" . $code . "&display=popup";
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token'];
}


// Attempt to query the graph:
$graph_url = "https://graph.facebook.com/me?"
. "access_token=" . $access_token;
$response = curl_get_file_contents($graph_url);
$decoded_response = json_decode($response);

//Check for errors 
if ($decoded_response->error) {
// check to see if this is an oAuth error:
if ($decoded_response->error->type== "OAuthException") {
  // Retrieving a valid access token. 
  $dialog_url= "https://www.facebook.com/dialog/oauth?"
    . "client_id=" . $app_id 
    . "&redirect_uri=" . urlencode($my_url);
  echo("<script> top.location.href='" . $dialog_url 
  . "'</script>");
}
else {
  echo "other error has happened";
}
} 
else {
// success
echo("success" . $decoded_response->name);
echo($access_token);
}

// note this wrapper function exists in order to circumvent PHP’s 
//strict obeying of HTTP error codes.  In this case, Facebook 
//returns error code 400 which PHP obeys and wipes out 
//the response.
function curl_get_file_contents($URL) {
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_URL, $URL);
$contents = curl_exec($c);
$err  = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
if ($contents) return $contents;
else return FALSE;
}
?>

for more details info you can visit this link
Thanks

like image 28
Danish Iqbal Avatar answered Oct 05 '22 11:10

Danish Iqbal


UPDATE

well you are doing something wrong you do not need to renew access token even if its expired all you need is sending user facebook id & content you want to post together to your server by ajax then post it without access token Just check up here

Publish Stream from the application - for non logged in user, using Graph API, php SDK

if you have publish_stream permission you dont need access token this is documentation for publish_stream https://developers.facebook.com/docs/reference/api/permissions/

Enables your app to post content, comments, and likes to a user's stream and to the streams of the user's friends. With this permission, you can publish content to a user's feed at any time, without requiring offline_access. However, please note that Facebook recommends a user-initiated sharing model.

like image 25
Pooya Estakhri Avatar answered Oct 05 '22 12:10

Pooya Estakhri