Peter Gross
Peter Gross

Reputation: 213

Facebook, Oauth, PHP and storing access_tokens in MySQL

I've started to hack around a function to pull in FB data via my site using PHP, but could do with some help about the re-authentication stages.

So far I have it so that a visitor can authenticate via FB and get their data. My next challenge is trying to make repeat visits work without having to re-authenticate.

Current Plan

To do this I am storing the access token I get on the first visit (in MySQL). When the visitor returns I retrieve this access token fro mthe db and using a cURL function try to get content using a URL like ...

$graph_url = "https://graph.facebook.com/me/home?date_format=U&limit=40" . "access_token=" . $access_token;

I then check the returned content for errors. If necessary, I send the visitors browser back to Facebook for authentication via a URL like this ...

$dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" . $app_id . "&redirect_uri=" . $my_url . "&state=" . $_SESSION['state'] ;

(I understand the URL used for the original authenticate must be the same in the first visit and any subsequent ones, so I've now got all switches in once script.)

This then returns the code (or request token). Using this code I can then use another cURL function to try and get a new access token using this new request token using a URL like this ...

$token_url = "https://graph.facebook.com/oauth/access_token?" . "client_id=" . $app_id . "&redirect_uri=" . $my_url . "&client_secret=" . $app_secret . "&code=" . $code;

The new access token is then returned in the body of the page and I can grab this, update the local MySQL db version and make further FB graph requests (using the $graph_url above).

The Problem

It looks like FB is returning the same access token to me on each call. I currently think I have the code write, and that I have misunderstood the FB/Oauth flow (but I of course could be wrong!).

So my questions are ...

(1) is it possible/right for FB to return the same access token (maybe for a set period)?

(2) Should I be using another/different URL or parameters to make the calls I've outlined above?

(3) Can anyone point me to an example script (using the Facebook PHP SDK or not) that does this sort of thing?

(4) Any other pointers, tips, etc?

I don't profess to be an expert with all this, but I have been working on this for a few weeks now and scoured various resources for examples, but obviously missing the point somewhere.

Thanks in advance. Pete.

Upvotes: 2

Views: 2177

Answers (1)

Andrew Kozak
Andrew Kozak

Reputation: 1660

(1) is it possible/right for FB to return the same access token (maybe for a set period)?

Yes, if you are requesting an access token for an already-valid user session, you will simply get the same token returned to you.

(2) Should I be using another/different URL or parameters to make the calls I've outlined above?

Your URL's look good at a glance. The best plan is to use Facebook's Graph API Explorer to check them.

(3) Can anyone point me to an example script (using the Facebook PHP SDK or not) that does this sort of thing?

I can offer a couple quickie helpers I wrote for a recent application that uses the Game/Score functionality Facebook offers. These may be more or less helpful for you:

// SERVER-SIDE
/**
 *  Simplified cURL function for Facebook API
 * 
 *  @param  string  $url    Properly encoded URL to cURL
 *  @param  string  $type   Expected return type
 *     
 *  @return string  $buffer Buffer of returned data (decoded if appropriate)
 *  
 *  @author Andrew Kozak  < www.andrewkozak.com >
 */
function doCurl( $url , $type='JSON' )
{
  $ch = curl_init();
  curl_setopt( $ch , CURLOPT_URL , $url );
  curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT , 10 );
  curl_setopt( $ch , CURLOPT_RETURNTRANSFER , 1 );
  $buffer = curl_exec( $ch );
  curl_close( $ch );

  if( strtolower( $type ) == 'json' )
  {
    $buffer = json_decode( $buffer );
  }    

  return $buffer;
}

/**
 *  Grab Data Thru the Graph API
 * 
 *  Structured call to the Graph API using cURL.  To grab general User info, 
 *  leave the $what parameter blank.
 * 
 *  @param  string  $token  User's access token
 *  @param  string  $what   API-specific reference to what data is requested
 *  @param  string  $who    
 * 
 *  @return string  $json   Decoded JSON object containing returned data
 * 
 *  @author Andrew Kozak  < www.andrewkozak.com >
 */
function graphDo( $token , $what='' , $who="me" , $type='JSON' )
{
  return doCurl( 
    "https://graph.facebook.com/{$who}/{$what}?access_token={$token}" , $type 
  );
}



// CLIENT-SIDE 
/** 
 *  Get User's Current Score
 * 
 *  Assumes global-scope definitions for variables:
 *    facebook_user_access_token
 *
 *  @author Andrew Kozak  < www.andrewkozak.com >
 */
facebookGetScore : function( p )
{
  var score_from_fb = '';

  $.ajax(
  {
    url: "https://graph.facebook.com/me/scores" ,
    data: 'access_token=' + facebook_user_access_token ,
    dataType: 'json' ,
    complete: function( data )
    {
      var responseText = $.parseJSON( data['responseText'] );

      score_from_fb = responseText['data']['0']['score'];

      if( p === true )
      {
        console.log( "Current score: " + score_from_fb );
      }            
    }
  });
} ,

/** 
 *  Set User's Score
 * 
 *  Passes client-side gamer score to a server-side PHP script to 
 *  set the score on Facebook without publishing the application's
 *  access token.
 *
 *  Assumes global-scope definitions for variables:
 *    facebook_user_id
 *    facebook_user_name
 *    facebook_user_access_token
 *    EXAMPLE.currentslide // Gameplay progress data
 *    facebook_application_access_token
 *
 *  @author Andrew Kozak  < www.andrewkozak.com >
 */         
facebookSetScore : function( s , p ) 
{ 
  $.ajax(
  {
    url: "http://www.EXAMPLE.com/actions/ajax/setscore" ,
    data: "id=" + facebook_user_id + "&access_token=" + facebook_user_access_token + "&name=" + facebook_user_name + "&score=" + s + "&last_seen=" + EXAMPLE.currentslide ,
    complete: function( data )
    {
      if( p === true )
      {
        console.log( data['responseText'] ); 
      }
    }        
  });
}

(4) Any other pointers, tips, etc?

My biggest tip would be to use the Facebook Graph API Explorer to structure your calls beforehand and to log everything while working through the responses (I assume you're using Firebug or something comparable); Facebook's API responses are not quite "standard" across all calls (even the requests aren't completely standardized) so you may not be able to trust your intuition at times.

Upvotes: 1

Related Questions