PHP Sessions

From Facebook Developer Wiki

Jump to: navigation, search

The problem is that sessions in PHP default to using a cookie to store the session ID, but cookies are not possible in FBML because the page is being sent through Facebook's servers. Facebook's servers will not forward COOKIE data from your server to the user agent (browser). So using plain php sessions will not work.


Contents

Method 1

To remedy this, the API session_key is used as the php session ID:

   session_id($facebook->api_client->session_key);
   session_start();

This is confirmed working, using require_login() beforehand.

  • In some cases the facebook session key may contain characters that are not allowed by php's session engine, in that case use this code:
   session_id(preg_replace("/[^A-Za-z0-9-]/","",$facebook->api_client->session_key));
   session_start();

Method 2

Some people have had problems with PHP sessions being persistent. As far as I know it is impossible to store the PHPSESSID in a cookie using FBML. So, you can take $_GET['PHPSESSID'] and set it equal to the Facebook session_key before calling session_start().

The current user's UID, and the Facebook session_key are passed in one of two ways to your script.

  • If your script is loaded as FBML OR the first time you script is loaded within an iframe $_REQUEST['fb_sig_user'] and $_REQUEST['fb_sig_session_key'] will be set.
  • If you click on a link within an iframe, and load another regular page within the same iframe, then $_REQUEST['api_key_user'] and $_REQUEST['api_key_session_key'] are set, where $API_KEY is set to your unique API key.

The following code creates or retrieves a session based on the users facebook session_key then seeds it with the fb parameters from the request.

 $API_KEY = '...';

 $prefix = ($_REQUEST['fb_sig_user']) ? 'fb_sig' : $API_KEY;

 if( isset($_REQUEST[$prefix.'_session_key']) ){
    session_name( $_REQUEST[$prefix.'_session_key'] );
    session_start();

    $_SESSION['fb_user']        = $_REQUEST[$prefix.'_user'];
    $_SESSION['fb_session_key'] = $_REQUEST[$prefix.'_session_key'];
    $_SESSION['fb_expires']     = $_REQUEST[$prefix.'_expires'];
    $_SESSION['fb_in_canvas']   = $_REQUEST[$prefix.'_in_canvas'];
    $_SESSION['fb_time']        = $_REQUEST[$prefix.'_time'];
    $_SESSION['fb_profile_update_time'] = $_REQUEST[$prefix.'_profile_update_time'];
    $_SESSION['fb_api_key']     = $_REQUEST[$prefix.'_api_key'];
 } else {
    // Just so there *is* a session for times when there is no fb session
    session_start();
 }

Configure Session with CakePHP Framework

You need to add this code to your app_controller.php to make $this->Session helper available

function beforeFilter()
{
$id = preg_replace("/[^A-Za-z0-9-]/","",$this->facebook->api_client->session_key);
$this->Session->id($id);  
}

More iFrame Information

by zombat

It turns out that even on an internal link inside your iframe app, Facebook modifies the request to pass along some parameters. For some reason, they have an entirely different, but also valid session key that comes along with every iframe request! This parameter is named after your Facebook Application api key. So if your application API key is "xyz123", every request inside your iframe gets a parameter called xyz123_session_key (as well as a few others, like xyz123_expires and xyz123_user).

After watching the associated expiry time for the main session (the original fb_sig_session_key) and this iframe-only session (xyz123_session_key), the light at the end of the tunnel appeared: the iframe-only session key expiry time actually gets updated occasionally. I haven't determined when or how (I assume it's an Ajax ping at some point), but nonetheless, it refreshes.

I waited for the original fb_sig_session_key session to expire, and sure enough the friend-related pages in my app started coughing up errors. At that point, I switched my locally-stored session key to the new iframe-only xyz123_session_key, and the problem was solved. That session works just as well as the original!

reference