How to use Facebook Single Sign-On without the PHP SDK

Originally published 2014-07-29 19:07:57 by Nathan England
related tags: facebook, facebook php sdk, single sign-on,


Authenticating Users with Single Sign-On

A while back I was working a project where the client wanted to implement a single sign-on system that would be integrated with the current user registration and sign-on system. The client also wanted users to have the ability to share comments with their friends on Facebook. Having never used Facebook (seriously, I didn't even have a Facebook account) I wasn't sure what that entailed. My background is in corporate web development, back-end development, and control panel stuff that the front end user never sees. The majority of front-end development I have done, up to this point, was using templates provided by the client and or design work provided by another developer. Design is not my strong suit. I'm a developer, not a designer...

I created the necessary Facebook account and managed to wrangle my way through creating my first app. I downloaded the Javascript SDK and the PHP SDK and began looking through it all. After having spent much time with all of it, let me make this very clear. If you intended to submit posts to your users timeline while the user is *not* actually on your website then you need to use the PHP SDK. If you are only going to offer the ability to post to a timeline, but the user must actuate it, then you want to use the Javascript SDK. If you want to allow users to register on your site, creating an actual account that is stored in your database, then you will likely want to use the PHP sdk. But, if you only want to provide easy account creation you can also do it without using the SDK at all. Adding the Javascript later is a snap and allows for easy sharing to users timelines.

Facebook Configuration

The first step necessary is to create your Facebook app on https://developers.facebook.com. That part of the process is beyond the scope of this document, not to mention they have changed the process for doing so twice since I originally started less than two years ago, so by the time you find this article they will likely have changed it again! Of course, email me and I would be happy to help out that way...

You will need an APP ID, an APP SECRET, and a Valid OAuth redirect URI. Copy and paste them into an editor somewhere. I suggest you create a config file to hold general information that will be used throughout this process. For this example I will create a file called facebook.config.php which will look like this: (hopefully these are not real APP ID and SECRET... ;-)

<?php // filename: facebook.config.php
// this is my facebook configuration details
define('FACEBOOK_APP_ID', '97237490283423');
define('FACEBOOK_APP_SECRET', '90982309842309482930849023582758');
define('HTTP_HOST', 'http://www.mydomain.com');
define('STATE', md5(uniqid(rand(), TRUE)));
define('FACEBOOK_REDIRECT_URI', HTTP_HOST . '/user/facebook/authorize.php');

Facebook Login URL

Before we can get any of the information we need about the user we need to provide the user with a login button. If you are going to create a class or at least a function use this:

function getLoginUrl() {
     $loginUrl = "https://www.facebook.com/dialog/oauth?"
          . "client_id=" . FACEBOOK_APP_ID
          . "&redirect_uri=" . FACEBOOK_REDIRECT_URI
          . "&state=" . STATE
          . "&response_type=code"
          . "&scope=user_about_me,email";
     return $loginUrl;
}

Now you can include this anywhere you want to provide a login button. Of course, this does not check if the user is logged in or out, it only provides the url so we can request the access token. When the user clicks the link it will send your Facebook APP ID to Facebook, along with your valid OAuth redirect URI. If everything matches what Facebook has in their systems then they will redirect the user to your redirect uri with a code as a GET field.

Requesting the Access Token

When the page is returned your first step is to compare the &state field with your own to make sure it is the same. The second step is to capture the code returned, we need that code to request an Access Token. So capture that code in a property or variable.

$facebook_code = $_GET['code'];

Next we will request the access token. Again, using a class is ideal, but a function works as well... For this one, we will create two functions. One will be a curl function to request the data.

function curl($url) {
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_URL, $url);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
     $data = curl_exec($ch);
     curl_close($ch);
     return $data;
}

function getAccessToken($facebook_code) {
     $token_url = "https://graph.facebook.com/oauth/access_token?"
          . "client_id=" . FACEBOOK_APP_ID
          . "&redirect_uri=" . urlencode(FACEBOOK_REDIRECT_URI)
          . "&client_secret=" . FACEBOOK_APP_SECRET
          . "&code=" . $facebook_code;
     $response = curl($token_url);
     $params = null;
     parse_str($response, $params);
     if ($params['access_token']) {
          return $params['access_token'];
     }
     return FALSE;
}

Using these two functions you can request the Access Token from Facebook.

$access_token = getAccessToken($facebook_code);

Pull the User from Facebook's GRAPH API

Verify that you received an access token and then you can move on to getting the users info. The next function will use the access token to retrieve the information we requested in the scope field in the original login request. The data will be pulled from the Facebook GRAPH API.

function getUserInfo($access_token) {
     $graph_url = "https://graph.facebook.com/me?access_token=". $access_token;
     $user = json_decode(curl($graph_url));
     if($user != null && isset($user->name)) {
          return $user;
     }
     return FALSE;
}

$user = getUserInfo($access_token);

You can now check that $user was populated and print the details.

print_r($user);

At this point you can capture the facebook_id and check your database for a matching id. If it exists you can be sure you have an authenticated user and log them in, if the facebook_id does not match, then store all of this data and create a new user.

Congratulations, you now have single sign-on!