NOTE: I had a version of this blog post in draft mode for months addressing the old (PHP SDK v2.1.2) Facebook PHP library.  In a fit of momentum, I am publishing this post now, updated to use the new library (PHP SDK v3.1.1).  Since I am not as familiar with the new one, there may be better ways to do the following, although the code below works.

Facebook authentication, much like the rest of the platform, can be maddening.  It appears easy enough at 1st glance, until you realize the contrived XFBML examples in the docs will not get you very far.  So then you might take a look at the advanced document. And then realize that the advance document, that giant, complicated, very detailed and thorough explanation of OAuth 2.0 as implemented by Facebook, does not actually help you code your website.

This blog post is more for my benefit than yours, and serves to summarize my current Facebook authentication strategy, so I don’t have to figure it out over and over. At least, until Facebook changes it.

My Requirements

First off, realize that there are 3 ways to do any particular thing on the Facebook platform: XFBML, JS, and PHP (server-side).

That said, I do not use the XFBML <fb:login/> button.  XFBML is great for non-developers who can copy and paste the documentation into a website and impress their friends.  But XFBML is slower, ties your user’s application session to your user’s Facebook session, and you can’t make general API calls, so you may as well learn how to use the JS or PHP SDKs anyway.

  1. Authentication flow must work with and without JavaScript, as we are targeting older smart phones, such as Blackberry Curves.
  2. I do not want to use Facebook to persist my application sessions.  I merely want to use Facebook for authentication and then use standard PHP sessions to maintain a user login.  Using the Facebook session as your application session (as in the case of XFBML above) is sucky.  You will noticed sites that do this because when you log out of the site, you will log out of Facebook, and vice-versa.  Logging out of your site should not log you out of Facebook.  Facebook sessions and your application’s session should be separate.  I want to use Facebook only to authenticate the user, that is, to confirm the user is who they say they are.  Foursquare does a great job of this.


First, I need a login login link that non-JS browsers can use.

<a id="fb-login" href="<?= $loginUrl ?>">Login</a>

That $loginUrl comes from:

$loginUrl = $facebook->getLoginUrl(array('scope' => 'offline_access'));

The login link will ask the user for offline_access permission, as an example.

Then we need some the FB JS SDK to handle the link for those of us with modern browsers.

FB.init( { appId: 'XXXXXX', status: true, cookie: false, oauth: true } );
$('#fb-login').click(function(e) {
  FB.getLoginStatus(function(response) {
    // maintain application anchor/query string, if any
    q =;
    if (window.location.hash) {
      q = window.location.hash.split('?')[1];
    // if already logged in, redirect
    if (response.authResponse) {
      window.location.href = '/?signed_request=' + response.authResponse.signedRequest + '&' + q;
    } else {
      // else present user with FB auth popup
      FB.login(function(response) {
        // if user logs in successfully, redirect
        if (response.authResponse) {
          window.location.href = '/?signed_request=' + response.authResponse.signedRequest + '&' + q;
      }, { scope:'offline_access' } );

Couple interesting things to point out:

  1. In the call to FB.init(), the cookie flag is set to false.  In most FB examples, this flag is set to true.  If this flag is true, the JS will set a cookie (that begins with ‘fbsr_’) that will keep the user connected to your Facebook app during a browser session.  This can confuse your app, because if you do not clear this cookie when your user logs out, your app may automatically re-authenticate your user.  If you do intend to use your user’s Facebook session as your website’s session, set this flag to true.
  2. On lines 16 and 25, as in most FB examples, a simple window.location.reload() might appear.  This only works if the JS sets the Facebook cookie, as this cookie will tell the server that the user is authenticated after the reload.  Since we can’t use the cookie, we need another way to tell the server if this login attempt was successful.

Server side

On the server-side, Facebook will tell us if this user is who he says he is with the getUser() method.  If this method returns a non-zero user ID, then Facebook has authenticated this user, and we can create a normal PHP login session, however you usually do that.

$id = $facebook->getUser();
if ($id)
    // login successful
    $_SESSION['user'] = $id;
// redirect to user dashboard or something
header('HTTP/1.1 302 Found');
header('Location: /');

getUser() tries to authenticate a few different ways.  You can read the code in the PHP SDK if you’re really curious. One way is from the ‘fbsr_’ cookie.  Another is by checking for the signed_request in the query string.  Remember when we passed that in earlier via JS?   The cool thing is, that even in the non-JS case, Facebook will send that signed_request in the query string, so this code will function the same in both cases.

Keeping the user logged in as he makes requests is the same as usual.  I simply check for the flag (or, in the example above, a user ID) to verify authenticated status.

To logout, I can simply clear the PHP session like normal.

// logout
// redirect to external home page
header('HTTP/1.1 302 Found');
header('Location: /');

Again, this does not log me out of Facebook


When might you want to use your user’s Facebook session for your user’s website session?  I think the only case you would do that is if your web app is a Facebook-centric application.  That is, if every feature of your app involves Facebook somehow. In that case, maybe it makes sense because your user cannot use your app without being connected to Facebook.

You can find a fully working example of this flow on my GitHub.  This really belongs in an MVC-type framework, but for simplicity I put everything in a giant if/else statement.  Throw the files in a webroot, add your app’s ID and secret to the PHP file, and try it out. Try it with JavaScript enabled and disabled.  After logging into the example, try logging out of Facebook, and then logging out of the example, and vice-versa. And let me know if you spot anything fishy.