Facebook PHP SDK and CodeIgniter for basic user authentication
With CodeIgniter 2.0, 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.
Important: Facebook released a new SDK (version 3.0+) that dropped cookie support. This means, that the new SDK will not work with the XFBML buttons or the JavaScript SDK we are used to. For the new SDK to work, we have 2 options:
a) Use the standard login and logout URL that redirects the user to Facebook and then back to our site.
b) Modify the FB SDK to allow the use of cookies, which inherently allow us to us the JavaScript SDK and the cute FB login button plugin. As far as I know, the Facebook guys are working on re-implementing this feature on their SDK, but I don’t know when that’s going to happen.
In this article I will cover only the first case. Editing the Facebook SDK to support cookies takes a bit more work and it will be covered in a different post once I finish doing some testing (yes, I am working on my own implementation).
Update: Facebook updated the SDK to support cookies again. So, we can go back and use the JavaScript SDK or even XFBML for the login and logout buttons.
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:
http://developers.facebook.com/docs/reference/api/
All the methods related to the user object (very useful): http://developers.facebook.com/docs/reference/api/user/
First of all, a couple of links so you can download the necessary files:
CodeIgniter Reactor: 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:
- Autoload the CodeIgniter Session Library from application/config/autoload.php
- 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.
- Once you download the FB 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.
- Rename the file “facebook.php” to “Facebook.php” (notice the F in capital) present in your application/libraries folder.
- 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.
<?php
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:
<body>
<div>
<?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 src="https://graph.facebook.com/<?php echo $fb_data['uid']; ?>/picture" alt="" class="pic" />
<p>Hi <?php echo $fb_data['me']['name']; ?>,<br />
<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> </p>
<?php endif; ?>
</div>
</body>
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.
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,


Hello all,
It’s not working, please help..
The problem is after logging in to facebook, it will redirect back to site and not logged in, with a request code..
How can I fix this?
link: http://www.dailydealso.com.au/facebook_test
Warm regards,
Reland
I checked the URL and it seems like CI is not grabbing the GET vars. 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.
Hy Danny! Thanx for the tutorial and coding. I have the same problem mr. Reland Pigte have. The address is http://www.matchifier.com/welcome
The allow_get_array is true, the sessions are loaded in the model. Can you tell me why isn’t it working ?
Hello again! I found a fix for my problem that a logged user is redirected to a page that don’t see it logged in. It’s very simple: the redirect url when you log in must be the first page of your application, the controller set in your routes.php as first page. I personally changed in getCurrentUrl() function the line below:
$currentUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
with:
$currentUrl = $protocol . $_SERVER['HTTP_HOST'] . ‘/index.php’;
Now it works! Please tell me if it’s working to you!
I have been struggling with solving a problem of “log out”. I’m using your codes, it works in my setting apart from “log out”. when clicking log out, it logs out facebook, but it doesn’t log out from my site. As if i didn’t log out, i can walk around in my site. Site is : http.//hatirnaz.turkemedya.com
I use the method:
$friends= $this->facebook->api(“/$user/friends”);
and properly receive friends
but if use:
$likes = $this->facebook->api(“/$user/likes”);
I get an empty object
why?
ps:
I also tried with the url as written here:
https://developers.facebook.com/docs/reference/api/
with the same result
help please!
ok I solved it was only a matter of the application permits
Hey,
you said something about application permits, maybe you or somebody else can help me. I try the following to change the application scope (as of sdk 3.0), but it doesn’t want to work.
$fb_data = array(
‘me’ => $profile,
‘uid’ => $user,
‘loginUrl’ => $this->facebook->getLoginUrl(array(‘scope’ => ‘email, publish_stream, user_birthday’)),
‘logoutUrl’ => $this->facebook->getLogoutUrl(),
);
even changing the loginUrl to a plain string ‘myLittlePinkBunny’ doesn’t work. Looks like for some reason the loginUrl is generated elsewhere and not in the Model as described in the tutorial.
Hope someone can help me!
Thx M
Dear all,
I have one problem with facebook connection.
when I click on login it go to login normally, but after I logined it redirect to my site.
the problem is I see login the same, until I click on login again I can see “Hi my name” and photo and can logout.
Please any one help
regards
I’m noticing the same log-out issue. It’s not clearing the fb_data array in the session and keeping me logged in on my site even though I’m no longer logged into Facebook. I tried even unsetting that array in my site’s normal log out flow and it persists! I’m wondering if it’s because the library is being auto-loaded and overriding my session unset. Either way it’s one of those maddening bugs. Otherwise I got this working first go round and it’s great!
Thanks for any help on this one!
Hi
I am also having same issue. Can’t logout. Could you be more specific how you solved this issue.
Thanks
Ajit
If you are having problems getting the Access token back after logging in, I had to change base_facebook.php and replace all $_REQUEST with $_GET. Somehow that fixed it. Specifically the getCode function, after logging in it always had the code and state in the URL, yet wasn’t getting it with REQUEST. Hopefully this helps
Has anyone had problems after updating to PHP SDK 3.1.1? I’ve reverted to 3.1.0 (which doesn’t work with JS SDK), because 3.1.1 with CI would never detect the user as connected.
As CI 2.0.3 has been stable for a while I still see the same strange behavior. If I switch back to CI 2.0.2 it works, with CI 2.0.3 it doesn’t. Has anyone got an idea? When I click on the “Login with Facebook” link I’m re-directed to my application and still logged out.
I have to start a new project soon that will be based on the new CI version and also the new FB SDK version. I will test everything and post the update as soon as its finished. Sorry for the delays.
I have uploaded files that u have provided. It isnt working for me.
You can see that here : http://apps.facebook.com/testciapp/
Thanks a lot , it helped me a lot.
I am having the same problem as chuch above. I can login but it seems flakey.
Sometimes I hit login, I am sent to the facebook site, login then get redirected back to my test site (on localhost) and i am logged in fine.
Other times I do exactly the same but when i get redirected back to my site i see the login button still. I click it again and the page reloads and I can see my user data.
Any idea whats going on? I tried replacing all $_REQUEST in base_facebook to $_GET but it didn’t make any difference.
Thank you. Very helpful
I have the Facebook javascript sdk and facebook php sdk working with codeigniter somewhat.
If I login with the javascript sdk I have to refresh the browser once and all the facebook data is there. The javascript has the page reload, but that is not enough. I have to physically hit the refresh button on my browser.
If I can just figure out why the page needs refreshed twice to get the data then my app would be ready to roll.
Hello.
it doesn’t word with php sdk 3.1. getUser return null. Someone has a solution?
Excellent stuff, works a treat! I appreciate you spending the time and effort to put this online.
Hey thanks for the well defined tutorial.
Ive implemented the same in my project.
My problem is that authentication is working perfect on my local server.
After implementing on hosting server im facing one problem that is :-
from base url ( http://jumbotv.in/nib/ ) authentication is working properly but when im trying to make it from another controller its not working, not getting session.
Just visit the URL and you would know the situation.
Kindly Respond me ASAP
Thanks alot! You’re the bomb! I am just starting on code-igniter and this helps a lot!
Thanks for your tutorial. It is very useful to me. Specially this line.
CURLOPT_SSL_VERIFYPEER => false,
Hi Danny, i try to set $config['allow_get_array'] = true, but this can’t grabbing the get vars.
When i access http://inibayiku.com/cifb/
it can grab the vars,
but when i access http://inibayiku.com/cifb/welcome
it can’t grab the vars..
can you help me, why the problem ??
Hi,
everyone with the “I have to login twice problem”. It has something to do with the the not unsetting of fb_appId_state. I haven’t figured out what the problem was but this small hack in facebook_model.php solved it for me.
If you add this just before the end of the script
if(isset($_REQUEST['state'])){
unset($_SESSION['fb_'.$config['appId'].’_state’]);
}
so just before
$this->session->set_userdata(‘fb_data’, $fb_data);
}
}
Hi There,
First off thanks for the tutorial it helped a lot. However I found that by changing the filename ‘facebook.php’ to ‘Facebook.php’ didn’t work out so well for me. I just kept both the file and the library load ($this->load->library(‘facebook’, $config) all lowercase and then it started working.
Getting this Error!
CI Error:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Home::$session
Filename: core/Model.php
Line Number: 50
PHP Error:
Fatal error: Call to a member function set_userdata() on a non-object in /application/models/facebook_model.php on line 42
You have to autoload session library. I had the same problem as you have.
Please autoload the session library.
Works great! Thanks a lot!
The issue with logout is solved like this:
1. In View:
<a href="home/logout/”>logout
2. In Controller (home.php):
function logout($fburl)
{
session_destroy();
redirect($fburl);
}
This worked for me.
Just a heads up, I had trouble with this because CI was stripping data from $_GET and $_REQUEST and placing it in the input class, meaning the facebook API couldn’t receive the facebook login reply. If you have these problems, you’ll have to replace facebook’s calls to $_REQUEST with calls to CI’s $this->input->get();
Thanks for the script though.
Marques: It worked! I debugged the app and $_REQUEST has been altered by Codeigniter. I changed $_REQUEST by $_GET in all the code and it worked!
Thanks a lot! U helped me!!!! =))
hello, i just can see a empty page, i don’t know what is wrong! Any ideas?
I’m using the new version CI and PHP SDK.
Yasmine. Though showing errors in enabled on the application level, it might not be on the php.ini. Which prevents errors from showing. To fix this issue do the following
on the index.php on the root add the following line:
ini_set(‘display_errors’, 1);
So the case ‘development’ should be something like this
case ‘development’:
error_reporting(E_ALL);
ini_set(‘display_errors’, 1);
Now you’ll start getting errors and you’ve to start fixing them
.
best of luck
hello, I identified that my problem are in the line on my model, but yet don’t know how I can do it works:
$this->load->library(‘Facebook’, $config);
if I comment this line the view shows a error message, but when uncomment this line the view shows a blank page.
The error is most likely due to a missing library or any problem with the configuration. In order to easily identify the problem, I’d suggest you to enable development mode on the index.php file of your CI installation.
A blank page means an error that php is not displaying because of the error_reporting configuration of your index.php file.
I’m using php -sdk 3.1.1 and CI 2.1.0
My CI it’s already in development mode and still I get a blank page
Hello! Your code helped a lot! Thank you!
Hey Danny, thank you so much for the tutorial. I went through many tutorials and this one seemed to be the most promising.
I followed all your instructions (and even some added in the comments) but sadly, I’m still unable to get the login to work and I’m not too sure why. My getUser() function still keeps returning 0, even though I’m logged in on Facebook and have approved my application (which happened after I clicked the login button). From what I read, it has something to do with my sessions being saved? I have always been using CI Session and there has not been any problems, so I’m not too sure if it’s session-related.
Currently, the only thing that happens after I click the login button is that these characters “#_=_” get appended to my URL.
I would greatly appreciate your input.
Ah problem fixed finally.
1) Make sure the redirect URL is not redirecting to somewhere else. For example, I am using Tank_Auth, so I was redirecting auth/index to auth/login;
2) Change $_REQUEST['state'] and $_REQUEST['code'] to $_GET['state'] and $_GET['code'];
Thanks Danny & commenters!
You’re the man, thanks!!
The only way I could figure out how to fix the must log in twice problem is to add this to facebook_model.php
if(isset($_REQUEST['state']) && !$fb_data['uid']){
redirect($fb_data['loginUrl']);
}
right before this line
$this->session->set_userdata(‘fb_data’, $fb_data);
Hey! Thanks so much for posting this!
I’m trying to save additional user data in the session and it seems that loading / adding the Facebook_model model wipes out any additional data that I try to store in the session. (ie: between consecutive reloads of the page any data I stored with $this->session->set_userdata(‘userid’, 9) does not get saved)
Have any of you seen this problem / have any ideas on what to do?
Thanks!
’9kwuh
Have not seen that problem before. The only issue I had with sessions on CI in the past was because my sessions table wasn’t up to date with the latest CI version. Make sure you’re using the latest table structure so the session data can be saved properly.
Hey thanks for this, looks great. I just have a few questions if anyone has has time to answer:
- Is the login checked with Facebook every time Facebook_model is loaded? Yes?
- Is the login checked with Facebook every time $this->session->userdata(‘fb_data’); is called? No?
Basically just trying to keep load times down as much as possible. So essentially I can only load Facebook_model once to set the session data, then use $this->session->userdata(‘fb_data’) whenever I want to use their Facebook details, and only have to call Facebook_model when I want to refresh their FB status?
Sorry – just getting used to working with Facebook. I noticed loading Facebook_model adds about 1 second to render time for the app, so i only want it to talk to FB when I really need it to.
I hope that all makes sense!
Many thanks,
Tom
Yes, in theory, you’re right. However, if you don’t constantly check against the Facebook SDK for a valid FB Session, you could probably end up with broken user information. There are a couple scenarios that could happen while the user is browsing your website:
a) The user logs out of Facebook from another window. You must know that as soon as your website refreshes.
b) The user drops the app permissions from their FB account in another window or browser. You absolutely need to detect this and act accordingly on your next page refresh; only if you need special permissions on your app.
c) The Facebook session expires for that browser (cookie). As soon as your website refreshes, you need to ask for the login information again.
If any of those scenarios is present and you’re not validating the user-data against the FB SDK, then you might end up with a broken app. Probably asking the user to perform actions that can’t be completed without a valid FB session or ever requesting information that is just not there.
Yes, pulling info from the FB SDK is slow and will affect your response times. However, there are some cases where you don’t need to check for a valid FB session, like on static pages, home page, contact us page, etc.
Have fun!
Please try the updated code sample. It should work out of the box.
Hey! Thanks a lot for the post. I am getting an error after clicking the login url. I don’t know why it is showing.
It shows
“Error
An error occurred. Please try again later.”
Do you have any idea?
Thanks
That’s an internal FB error. Please check that you’re passing the right parameters to the Facebook SDK. If you’re using a wrong app-id, app-secret or app-permissions, FB will give you some errors here and there.
I have checked it. Everything is right. But don’t know why it’s not working. Will I need to keep the site url (in fb) and redirect url identical?
Hey Danny,
Thanks again for the article! I ended up having to strip out codeigniter sessions as they weren’t working but i got it working with base PHP sessions.
I”m having one issue with the facebook logout:
1. Log in to my app or fb (either)
2. Log out of facebook
3. My app successfully logs out
4. when I try to log in again, nothing happens now.
Any ideas on what is going on? I just keep getting redirected back to the original login page with some weird character at the end of the url. Thanks in advance!
I followed the step which mentioned above but till the login is not working.
the error which showing is An error occurred. Please try later.Please,help me to resolve this problem.
Thanks Darren, your tutorial is definitely the best one
…
I have wrote a small blog that over comes some of the issues I faced and the solution was not mentioned here. After you’re done with this tutorial and if you still have issues, please visit http://abuhijleh.net/2012/04/07/guide-facebook-login-with-codeigniter/
I suggest solutions for the following issues:
1. Getting blank page
2. Page does not refresh after login
Best of luck
logout issue try to use javascript FB API
https://developers.facebook.com/docs/reference/javascript/
it working fine for me.
Thanks! I struggled for hrs for that fix and your suggestion works. Was getting getUser() result 0 until I set $_REQUEST to $_GET.
Hey! Thanks so much for posting this!
Message: Undefined property: auth::$session
Filename: core/Model.php
Could you have any idea why it’s not working?
Please autoload your session library.