Facebook PHP SDK and CodeIgniter for basic user authentication

Posted by on Feb 24, 2011 in CodeIgniter, PHP | 205 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,

205 Comments

  1. Steff
    April 24, 2012

    HI – I am having trouble getting my site to logout. It runs through the fb logout url and then lands back on my initial login page, but the session still exists. So the site still thinks that I am logged in. Is there a way to dump the session and then send the user to the fb-logouturl page?

    I didn’t quite understand Yura’s post (January 25th, 2012 9:48am)

    cheers!

    Reply
  2. sethumadhavan
    May 7, 2012

    this one is working for me….

    i added one method in facebook_model like

    public function fbLogout()
    {
    $this->facebook->destroySession();
    }

    and added logout method in my controller

    function logout()
    {
    $this->facebook_model->fbLogout();
    $this->session->sess_destroy();
    $this->session->userdata = array();
    redirect(‘login’);

    }

    Reply
  3. Cosmin
    May 7, 2012

    I’m struggling with the same problems for a few hours now, and nothing works.
    If I use the method in the tutorial it logs out from FB, but it doesn’t destroy the session on the page, so I it displays logout instead of login.

    If I use session_destroy() it works, but it doesn’t destroy the fb session.

    sethumadhavan unfortunatly your method doesn’t work for me. it doesn’t logout from facebook, neither from my page.

    Reply
  4. Pim
    May 24, 2012

    I also had the problem of the session which keep existing.

    Sethumadhavan’s solution didn’t work directly for me, since the Facebook object doesn’t have a method called destroySession()

    So what I did was making the clearAllPersistentData() a public method and calling it from the Facebook_model->fbLogout()

    Bad practice? Perhaps. But solved it for me.

    Reply
    • thinkdj
      September 10, 2012

      I’d downloaded the latest SDK when I started with this tutorial and it does seem to have destroySession();

  5. Brynleif
    June 13, 2012

    Thank you very much for having uploaded this and for keeping it updated. I would be pretty lost without this. I am having a problem that I am unable to understand, I hope someone here would like to help me out.

    I have managed to log in to the CI-page with Facebook and I can see the username and the picture. So far so good. Everything I need seems to be stored successfully in the CI-session. But when I open the topsecret function in the welcome-controller, this data doesn’t seem to exist. The function begins with $fb_data = $this->session->userdata(‘fb_data’);, but when I echo $fb_data['uid'] I get 0. I go back to the welcome page, and everything works perfectly.

    Sessions are auto-loaded, so I don’t understand what is causing this. Does anyone see what I am missing?

    Thank you.

    Reply
  6. Kamaldeep Singh
    June 17, 2012

    Hi Danny,

    Thanks for updations.I am creating facebook login app with Codeigniter.Login functionality is working fine with codeigniter but when m clicking on logout url(facebooklogout url),created url is fine (means all params are containing in url) but its redirect to me facebook.com and session doesnot destroyed.
    I had tried manually delete session by calling facebook->destroySession but this will delete facebook session from my site but not from facebook.com.
    Please provide me its solution.Its urgent basis for me. Thanks in advance.Hope you can understand my problem and try to give solution to me

    Reply
  7. SImon Barker
    June 21, 2012

    Hi Danny,

    This tutorial has been invaluable in getting facebook login working on my side project so thank you for writing it, but I am having issues making the session data persist.

    The only way that I can make the $fb_data persist is to load the model in the construct of my controller class. This means that operations which work regardless of weather a user is logged in or not are slowed up by the GET requests made by the facebook class.

    This is a pain and means that I have to load the class on an as needed basis, rather than just for login and log out. Otherwise the session data does not persist. Why does the facebook session data not persist and can this be changed?

    Also, I noticed that when using this class the session ID is updated on every page refresh but not if it is removed.

    Any help in solving this issue would be great.

    Simon

    Reply
  8. Kriss
    July 2, 2012

    Everything is working fine apart from “Logout”, The logout link does not destroys the session. Does anyone has some idea?

    Reply
  9. pawel
    July 4, 2012

    The login doesn’t work – It’s just linking to the current page – why?

    Reply
    • Abhijit
      August 13, 2012

      Hi Danny.

      I am also getting same issue.It goes to Facebook App.After approval it comes to login page again.

      When I print_r($fb_data) $fb_data['uid'] is set to 0.

      I am not able to see picture or logout link.

      Thanks in advance.Please Help

      Regards,
      Abhijit

  10. Prabin Shrestha
    July 28, 2012

    I am having the same problem. can someone help me out from this?

    Brynleif :
    Thank you very much for having uploaded this and for keeping it updated. I would be pretty lost without this. I am having a problem that I am unable to understand, I hope someone here would like to help me out.
    I have managed to log in to the CI-page with Facebook and I can see the username and the picture. So far so good. Everything I need seems to be stored successfully in the CI-session. But when I open the topsecret function in the welcome-controller, this data doesn’t seem to exist. The function begins with $fb_data = $this->session->userdata(‘fb_data’);, but when I echo $fb_data['uid'] I get 0. I go back to the welcome page, and everything works perfectly.
    Sessions are auto-loaded, so I don’t understand what is causing this. Does anyone see what I am missing?
    Thank you.

    Reply
  11. nicky
    August 4, 2012

    it never logout

    Reply
  12. amard
    August 27, 2012

    logoutUrl only logout user from facebook account, it does not clear your site session data. you need to call codeigniter sess_destroy()

    Reply
    • David
      September 27, 2012

      Hi, I have tried this, and still can’t seem to get the logout function to work as I expect. I expect it should reload the welcome view (through the index function in the welcome controller) and show the login link once again.
      When I click the logout link, yes I get logged out of fB, and yes the welcome page reloads, but it still shows the link to the secret page.
      Any ideas?

  13. Bohara
    September 12, 2012

    A PHP Error was encountered
    Severity: Notice

    Message: Undefined property: Welcome::$session

    Filename: core/Model.php

    Line Number: 51

    Fatal error: Call to a member function set_userdata() on a non-object in C:APM_Setuphtdocsapp_nameapplicationmodelsfacebook_model.php on line 47

    Reply
  14. Pete
    October 5, 2012

    To fix logout you can simply add a new controller which will be the same as the 1st one only that you can add a new function:

    function logout()
    {
    session_start();
    session_unset();
    session_destroy();
    session_write_close();
    setcookie(session_name(),”,0,’/');
    session_regenerate_id(true);
    redirect(‘welcome’,'refresh’);
    } // end of logout

    Also you need to fix the views so as to call the new controller’s function:
    NEW_CONTROLLER_NAME/logout

    and remove or comment out the load of the model:

    $this->load->model(‘Facebook_model’);

    Reply
  15. codeigniter x fb connect | code@butterflybone
    October 9, 2012

    [...] http://www.dannyherran.com/2011/02/facebook-php-sdk-and-codeigniter-for-basic-user-authentication/ This entry was posted on Wednesday, October 10th, 2012 at 12:14 pmand is filed under web. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. [...]

    Reply
  16. Agencja interaktywna CRENEO
    October 14, 2012

    Thank you very much – we use it in many projects for our customers.

    Reply
  17. Ryan
    October 21, 2012

    I also get blank/0 $this->session->userdata(‘fb_data’). Any solution? This worked once and then never worked again, although the code didn’t change.

    Reply
    • Danny Herran
      October 22, 2012

      Ryan,

      Try and update the SDK. Download it again from Github and give it a shot. That SDK has changed recently. However, the CodeIgniter code should remain the same.

  18. Tom
    November 8, 2012

    Hi Danny
    Thanks for this – great work.

    Will this work if I combine the JS SDK for login and the PHP SDK for the rest? If so could you give me an example?

    Cheers

    Reply
  19. Szymon Miałkas
    December 17, 2012

    Thanks for this, it was very useful.

    Reply
  20. ardi
    January 8, 2013

    hey danny.. the code is work at localhost but when i am implementing at app facebook its not working..the uid return 0 and me profile is null…any solution??

    Reply
  21. Danny Herran
    January 8, 2013

    ardi :

    hey danny.. the code is work at localhost but when i am implementing at app facebook its not working..the uid return 0 and me profile is null…any solution??

    This happened to me a few days ago in an old app. It was because I didn’t have the latest Facebook PHP SDK and SSL certificate installed. Can you please download and install the latest SDK? Also make sure you are using sessions, that the app URL is properly configured on Facebook and that the app permissions have been accepted.

    Reply
  22. ardi
    January 10, 2013

    hmm..i already use latest facebook php sdk and i already check ssl certificated have successful installed. maybe the problem is session, or app configuratuin

    Reply
  23. ardi
    January 10, 2013

    any solution danny? how to make sure i’m using sessions properly and app url is properly configured?

    Reply
  24. ardi
    January 15, 2013

    if my app Curl enabled can make this error solved??because my app curl is not enabled now??need answer :D

    Reply
  25. Yasir Hussain
    May 20, 2013

    Thanks for such a nice and up to date article. helped me save alot of hours :)

    Reply
  26. Rod
    June 8, 2013

    Danny,

    I’m having the next problem

    If i use the login example (http://www.kaltin.com/index.php/example
    ) first time i had an error HTTP 500 error
    Module FastCgiModule
    Notification ExecuteRequestHandler
    Handler PHP via FastCGI (*.php)
    Error Code 0×00000000

    if i refresh the page i saw the fb session

    I had my CI config with $config['permitted_uri_chars'] = ‘a-z 0-9~%.:_-#_=_’;
    $config['allow_get_array'] = TRUE;

    Latest CI and Latest FB SDK

    Any help? sorry for my english

    Reply
    • Danny Herran
      June 8, 2013

      Hello there. This is an IIS7 specific error handling the GET variables in your request. I tried it myself, and when you drop the variables, it works just fine. I am not an IIS expert myself, so there isn’t probably much information I can provide. I would contact my hosting provider with the full error description so they can sort it out.

  27. Rod
    June 8, 2013

    Thnks Danny i really appreciate that!

    Reply
  28. Rodrigo
    June 12, 2013

    There were an error with the PHP version, we change the FB SK to the version 3.0 and we solved

    Thankyou Danny

    Reply
  29. renz
    August 2, 2013

    it shows blank in my facebook how to fixed this i already change the sdk.

    Reply
  30. Theavuth
    August 7, 2013

    I have an error with this message, who can assist me?

    The redirect_uri URL must be absolute

    Thanks in advance

    Reply
  31. Facebook Covers
    August 9, 2013

    It’s really helpful tutorial. thank you for sharing.

    Reply
  32. Cliff
    November 2, 2013

    Hey I know this is off topic but I was wondering if you knew of any widgets I could add to
    my blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time and was
    hoping maybe you would have some experience with something
    like this. Please let me know if you run into anything. I truly enjoy reading
    your blog and I look forward to your new updates.

    Reply
    • Danny Herran
      November 3, 2013

      Take a look at AI Twitter Feeds for WordPress. Does the job.

  33. Franklin
    November 4, 2013

    Hi, I’m working with Codeigniter. I’m usign facebook login. I did the same as you mentioned above. But not able to login into my webiste. If I print the fb_data then it returns array ‘me’ => null and ‘uid’ => 0. kindly help me to fix this issue.

    Thanks in Advance.

    Reply
  34. Franklin
    November 4, 2013

    Hi,

    I’ve fixed the previous problem. No I need one help. If I login in my website using facebook, I need to fetch the users details to store them in my db. It’s working. But for some facebook accounts, it can easily fetch the details such as name, email etc. But for some accounts it couldn’t able to fetch the email. I can get all the details except email for some accounts only. So please help me to find solution and solve this problem.

    Thanks.

    Reply
    • Danny Herran
      November 5, 2013

      Franklin, it happens sometimes because the SDK can’t get the user data. When this happens you have 2 options: You could do a loop in your code, if the data is not there, loop 3 times to request the API again using $this->facebook->getUser(). Another way is to let the user know that their data couldn’t be retrieved, so refreshing the page with any button would do it. Also make sure your sessions are configured properly.

  35. Jackson Echeverri
    November 11, 2013

    Excelente post Danny. Hoy en día sigue siendo de gran utilidad para muchos. Saludos!

    Reply
  36. Rui
    November 19, 2013

    What should be the behaviour when user login in FB through the website, but after that logout from the FB website?
    In my opinion user should also logout from the website. I’ve tried this example but after logging in, getUser() method always returns a valid user (even if logged out in FB).
    More details in here http://stackoverflow.com/questions/20033336/facebook-php-sdk-getuser-returns-a-valid-userid-after-logout-from-facebook
    Can someone help?

    Reply
    • Danny Herran
      November 19, 2013

      I replied to you on StackOverflow. Take a closer look at my code. You need to test if the API has a response and then update $user appropriately.

  37. Rui
    November 20, 2013

    I replied back. For how long should be expected to get the ID even after logging out from Facebook manually?
    Was it supposed to be like this?

    Reply
    • Danny Herran
      November 20, 2013

      Actually it is intended to be like that. The piece of code that I posted is coming straight from the FB example they had in Github. Somehow, the user ID is there most of the time, so in order to be completely sure, you need to make an API call, if there is no response, then you reset the user ID to null.

  38. Rui
    November 20, 2013

    Ok, thanks a lot for the support.
    Keep up the good work!

    Reply
  39. Rui
    November 21, 2013

    Just re-tested this and even after waiting a few minutes and user appears to be always logged in on Facebook. Don’t know exactly if I’m missing something, or eventually a bug on FB SDK or CI.

    Reply
  40. vishal
    December 3, 2013

    hey danny !, nice post ,. thanks a lot
    but i am getting uid=> 0

    Array ( [me] => [uid] => 0 [loginUrl] => https://www.facebook.com/dialog/oauth?client_id=some value&redirect_uri=http%3A%2F%2Flocalhost%2Fcards%2F&state=1cef569a0b18210693a4d534e46694d1&scope=email%2Cuser_birthday%2Cpublish_stream [logoutUrl] => https://www.facebook.com/logout.php?next=http%3A%2F%2Flocalhost%2Fcards%2F&access_token=some value )

    Reply
  41. Omotayo
    December 28, 2013

    Hi danny, I am currently testing on localhost and I am getting the 0. Please let me know if this is because I am running it on localhost. Thanks

    Reply
    • Danny Herran
      December 28, 2013

      Yep, you need to test it in a public server. It wont work properly on localhost.

  42. Pablo
    February 25, 2014

    hey danny !,
    I have problems,

    i am getting uid=> 0

    [me] => [uid] =>

    Reply
    • Danny Herran
      March 1, 2014

      Hi Pablo, have you tried testing it in a public server? the uid 0 issue is usually related to localhost testing.

Leave a Reply