Facebook PHP SDK and CodeIgniter for basic user authentication

Posted by Danny Herran on Feb 24, 2011 in Backend | 211 comments


With CodeIgniter 2, plugins are no longer an option. Usually you would just add the Facebook PHP SDK as a plugin and you were good to go, but now, you need to make a little modification to the SDK in order to use Facebook Connect on your CodeIgniter application. Lets start by explaining what is, how to get started and how to authenticate an user using the Facebook API.

In this post I will only cover the user authentication process using the Facebook PHP SDK. However, you can do almost anything with the API, just take a look at the official documentation if you have any doubts:

https://developers.facebook.com/docs/graph-api/using-graph-api/

All the methods related to the user object (very useful): https://developers.facebook.com/docs/graph-api/reference/user/

First of all, a couple of links so you can download the necessary files:
CodeIgniter: http://www.codeigniter.com
Facebook PHP SDK: https://github.com/facebook/facebook-php-sdk (download the 3 files inside the /src/ folder).

Once you have your CodeIgniter set up, you can proceed to modify the Facebook PHP SDK and make it a library. What you need to do is the following:

  1. Autoload the CodeIgniter Session Library from application/config/autoload.php
  2. Facebook will try to pass the signed request via GET to your application. So, please make sure your CodeIgniter installation is set to allow the GET array. To do this, find the $config[‘allow_get_array’] in your application/config.php file and set it to TRUE.
  3. Once you download the FB PHP SDK, go to the “src” folder of the downloaded package and copy the “facebook.php”, “base_facebook.php” and “fb_ca_chain_bundle.crt” files to your CI application/libraries folder.
  4. Rename the file “facebook.php” to “Facebook.php” (notice the F in capital) present in your application/libraries folder.
  5. Add the following line to the beginning of the “Facebook.php” file:
    if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    

The next step is to build a model that will handle the authentication process. It basically requests the session data and saves it into a CI session var. The view and the controller can take care of the rest.

class Facebook_model extends CI_Model {
	public function __construct()
 	{
 		parent::__construct();
 		$config = array(
 						'appId'  =--> 'XXXXXXXXXXXXXXXXXXX',
						'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX',
						'fileUpload' => true, // Indicates if the CURL based @ syntax for file uploads is enabled.
						);

		$this->load->library('Facebook', $config);

		$user = $this->facebook->getUser();

		// We may or may not have this data based on whether the user is logged in.
		//
		// If we have a $user id here, it means we know the user is logged into
		// Facebook, but we don't know if the access token is valid. An access
		// token is invalid if the user logged out of Facebook.
		$profile = null;
		if($user)
		{
			try {
			    // Proceed knowing you have a logged in user who's authenticated.
				$profile = $this->facebook->api('/me?fields=id,name,link,email');
			} catch (FacebookApiException $e) {
				error_log($e);
			    $user = null;
			}
		}

		$fb_data = array(
						'me' => $profile,
						'uid' => $user,
						'loginUrl' => $this->facebook->getLoginUrl(
							array(
								'scope' => 'email,user_birthday,publish_stream', // app permissions
								'redirect_uri' => '' // URL where you want to redirect your users after a successful login
							)
						),
						'logoutUrl' => $this->facebook->getLogoutUrl(),
					);

		$this->session->set_userdata('fb_data', $fb_data);
	}
}

Now the controller(s). Here, you just have to load the Facebook model and validate the session vars accordingly:

class Home extends CI_Controller {

	function __construct()
	{
		parent::__construct();

		$this->load->model('Facebook_model');
	}

	function index()
	{
		$fb_data = $this->session->userdata('fb_data'); // This array contains all the user FB information

		if((!$fb_data['uid']) or (!$fb_data['me']))
		{
			// If this is a protected section that needs user authentication
			// you can redirect the user somewhere else
			// or take any other action you need
			redirect('login');
		}
		else
		{
			$data = array(
					'fb_data' => $fb_data,
					);

			$this->load->view('home', $data);
		}
	}
}

For the view we will use the native FB SDK login/logout URLs which are supported by default:

  <?php if(!$fb_data['me']): ?>
  Please login with your FB account: <a href="<?php echo $fb_data['loginUrl']; ?>">login</a>
  <!-- Or you can use XFBML -->
<div class="fb-login-button" data-show-faces="false" data-width="100" data-max-rows="1" data-scope="email,user_birthday,publish_stream"></div>
  <?php else: ?>
  <img class="pic" alt="" src="https://graph.facebook.com/<?php echo $fb_data['uid']; ?>/picture" />

Hi <?php echo $fb_data['me']['name']; ?>,

    <a href="<?php echo site_url('topsecret'); ?>">You can access the top secret page</a> or <a href="<?php echo $fb_data['logoutUrl']; ?>">logout</a>

  <?php endif; ?>

This is a rough example of basic Facebook user authentication for your site. You can do a lot more and once you get a hang of it, it becomes pretty easy to work with. If there’s any doubts or questions, don’t hesitate to fill the comments section below, I’ll be happy to help.

Download the sample code.

Update Nov 19th, 2013: refreshed links and verified it is still working with the latest SDK and CodeIgniter..

Update Mar 1st, 2012: information on the new SDK. Also added a small update for custom permissions on the login URL. Requested by Alexintosh.

Update June 13th, 2011: Updated for the Facebook PHP SDK 3.0 +

Update May 3rd, 2011: Some servers seem to fail on cURL SSL certificates. To fix it, open the base_facebook.php file and find “CURLOPT_USERAGENT” (around line 132). Below that line add this:

CURLOPT_SSL_VERIFYPEER => false,