Tutorial Details
- Topic: Facebook Connect, PHP
- Difficulty: Moderate
- Estimated Completion Time: 45 Minutes
Lately, there’s been quite a fuzz about lazy registration. It turns out that the less the user has to think, the higher the conversion rates are! What a thought! If everybody seems to have a Facebook profile, why not add a one-click user registration? I’ll show you how to do that today.
Step 1. The Setup
MySQL Table
Let’s begin by creating a database table.
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`oauth_provider` varchar(10),
`oauth_uid` text,
`username` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Quite simple: we will be setting up a table for user information with id, username, first and last name, the URL to the user’s picture, and registered date. Also, we’re adding both an oauth_provider and oauth_uid fields, to distinguish between different third party open authentication protocols and their identifiers. For example, let’s say that, next week, you decide that it’s a good idea to also let Twitter users in. Easy; you just set another value to the oauthprovider, and avoid duplicating oauthuid values.
The Facebook App
Let’s begin by creating a new application. Give it a name and agree to the terms and conditions. Next, grab both the API Key and Secret in the basic tab as shown below.
On the canvas tab, set both the Canvas URL and Post-Authorize Redirect URL to your localhost and path that the script will process — something like http://localhost.com/login_facebook.php?. Note the question mark at the end and the domain; both are required by Facebook. Simply set your hosts file to a valid domain name.
On the connect tab, set the Connect URL to the same value and set localhost.com (or the one you are using) as the Base Domain.
Now save, download the client library, and unzip facebook.php in the srcdir to a new directory created in the root.
Step 2. The Callback
The authentication flow has three steps:
- The local script generates a URL asking the user for permission
- Facebook returns to the Canvas URL specified with a GET parameter
- The GET parameter authenticates the session
Let’s make a quick test before registering and login.
# We require the library
require("facebook.php");
# Creating the facebook object
$facebook = new Facebook(array(
'appId' => 'YOUR_APP_ID',
'secret' => 'YOUR_APP_SECRET',
'cookie' => true
));
# Let's see if we have an active session
$session = $facebook->getSession();
if(!empty($session)) {
# Active session, let's try getting the user id (getUser()) and user info (api->('/me'))
try{
$uid = $facebook->getUser();
$user = $facebook->api('/me');
} catch (Exception $e){}
if(!empty($user)){
# User info ok? Let's print it (Here we will be adding the login and registering routines)
print_r($user);
} else {
# For testing purposes, if there was an error, let's kill the script
die("There was an error.");
}
} else {
# There's no active session, let's generate one
$login_url = $facebook->getLoginUrl();
header("Location: ".$login_url);
}
Now, go to http://localhost.com/login_facebook.php, and let’s see what happens. If you are redirected to Facebook and requested for permission, we are on the right track.
However, there might be two issues. The first one: if you’re redirected to Facebook, but it shows an error, there might be a missing value in the configuration. Go back to your application settings and check both the Connect and Canvas tabs and make sure the fields are ok as described above.
There might be another issue, where you see an error, like “Uncaught CurlException: 60: SSL certificate problem, verify that the CA cert is OK.” This happens because of the CURL settings. You’ll have to open facebook.php, find the makeRequest() method, and, inside the function, find this line:
$opts = self::$CURL_OPTS;
Immediately following it, add:
$opts[CURLOPT_SSL_VERIFYPEER] = false;
I hate hacking libraries, but I haven’t found another way. Well, let’s continue with user registration. I’ve also added a try/catch statement, because, if there’s an old session keys in the GET params in the URL, the script will die with a horrible error.
Step 3. Registration and Authentication
We’ll next be working with MySQL. Please note that I will not implement a data sanitizer, since I want to keep the code as short and on task as possible. Please keep this in mind: always sanitize your data.
First, let’s connect to the database.
mysql_connect('localhost', 'YOUR_USERNAME', 'YOUR_PASSWORD');
mysql_select_db('YOUR_DATABASE');
Now, let’s work on the $session conditional, in case we have a session.
# We have an active session; let's check if we've already registered the user
$query = mysql_query("SELECT * FROM users WHERE oauth_provider = 'facebook' AND oauth_uid = ". $user['id']);
$result = mysql_fetch_array($query);
# If not, let's add it to the database
if(empty($result)){
$query = mysql_query("INSERT INTO users (oauth_provider, oauth_uid, username) VALUES ('facebook', {$user['id']}, '{$user['name']}')");
$query = msyql_query("SELECT * FROM users WHERE id = " . mysql_insert_id());
$result = mysql_fetch_array($query);
}
Note that I’m querying the database, looking for facebook as a oauth_provider; it’s generally a good idea, if you want to accept other OAuth providers (as twitter, Google Accounts, Open ID, etc.) and a oauth_uid, since it’s the identifier the provider gives to its user accounts.
The oauth_provider field could potentially lead to bad performance if we leave it as a text field type. As such, the best option is setting it to an ENUM type.
We have now a $result var with the values queried from the database. Let’s next add some sessions. Add this line at the beginning of your script.
session_start();
After the empty($result) conditional, append the following:
if(!empty($user)){
# ...
if(empty($result)){
# ...
}
# let's set session values
$_SESSION['id'] = $result['id'];
$_SESSION['oauth_uid'] = $result['oauth_uid'];
$_SESSION['oauth_provider'] = $result['oauth_provider'];
$_SESSION['username'] = $result['username'];
}
As it makes little sense to authenticate a user who is already logged in, just below the session_start() line, add:
if(!empty($_SESSION)){
header("Location: home.php");
}
And in the scripts which require authentication, just add:
session_start();
if(!empty($_SESSION)){
header("Location: login_facebook.php");
}
And if you want to display the username, access it as an array.
echo 'Welcome ' . $_SESSION['username']; # or.. echo 'Welcome ' . !empty($_SESSION) ? $_SESSION['username'] : 'guest';
Step 4. Additional Methods
Facebook has a ton of connect features, but here are four that I’ve found to be the most useful.
Legacy Methods
I might be missing something, but the FQL seems more flexible and easy than the Graph API. Fortunately, Facebook still lets developers use it, altough with the new library, it has changed a bit.
If you want the user id, first name, last name, squared thumbnail for the user picture, the biggest user picture available, and his or her gender, you can use the users.getInfo method.
$uid = $facebook->getUser();
$api_call = array(
'method' => 'users.getinfo',
'uids' => $uid,
'fields' => 'uid, first_name, last_name, pic_square, pic_big, sex'
);
$users_getinfo = $facebook->api($api_call);
You can check the full list of fields available for Users.getInfo.
It is possible to achieve the same result, using FQL.
$uid = $facebook->getUser();
$fql_query = array(
'method' => 'fql.query',
'query' => 'SELECT uid, first_name, last_name, pic_square, pic_big, sex FROM user WHERE uid = ' . $uid
);
$fql_info = $facebook->api($fql_query);
Here’s the list of tables which can be accessed with FQL, as well as the fields available for the table users.
Extended Permissions
Facebook provides applications with some interaction with the user’s data – just as long as it’s authorized. With the old API, the authorization for additional permissions was exclusively available for the Javascript SDK (altough I’m not quite sure). With the new API, we can easily redirect the user to an authorization dialog in Facebook, and return to our site after the access is either granted or denied.
In the following example, we will be redirecting a user to authorize posts status updates, photos, videos and notes, the user’s real email address, birthday and access to photos and videos.
$uid = $facebook->getUser();
# req_perms is a comma separated list of the permissions needed
$url = $facebook->getLoginUrl(array(
'req_perms' => 'email,user_birthday,status_update,publish_stream,user_photos,user_videos'
));
header("Location: {$url} ");
Here’s a full list of permissions. Note that you can specify both the url to direct to if the user accepts and the url to be redirected to if the user denies. The key for these array elements are next and cancel_url, respectively. Here’s a quick example:
$url = $facebook->getLoginUrl(array(
'req_perms' => 'email',
'next' => 'http://localhost.com/thanks.php',
'cancel_url' => 'http://localhost.com/sorry.php'
));
If not specified, the default is the requesting script’s location.
Checking for Extended Permissions
Since the user can easily revoke permissions, the application should always check if a given permission is granted before using it, specially if it’s about publishing something. We will have to use the legacy API, as it seems it’s not fully implemented with the new one yet.
$uid = $facebook->getUser();
# users.hasAppPermission
$api_call = array(
'method' => 'users.hasAppPermission',
'uid' => $uid,
'ext_perm' => 'publish_stream'
);
$users_hasapppermission = $facebook->api($api_call);
print_r($users_hasapppermission);
The ext_perm will only support the old list of available permissions.
Publishing to the Wall
Let’s post something to the wall after verifying the user has the publish_stream permission.
# let's check if the user has granted access to posting in the wall
$api_call = array(
'method' => 'users.hasAppPermission',
'uid' => $uid,
'ext_perm' => 'publish_stream'
);
$can_post = $facebook->api($api_call);
if($can_post){
# post it!
$facebook->api('/'.$uid.'/feed', 'post', array('message' => 'Saying hello from my Facebook app!'));
echo 'Posted!';
} else {
die('Permissions required!');
}
Essentially, we are making an API call to /<user_id>/feed, using the POST method (second argument) and an array as a third argument for the data to be sent. In this case, this third argument supports message, link, picture, caption, name and description. Here’s the code:
$facebook->api('/'.$uid.'/feed', 'post', array(
'message' => 'The message',
'name' => 'The name',
'description' => 'The description',
'caption' => 'The caption',
'picture' => 'http://i.imgur.com/yx3q2.png',
'link' => 'http://net.tutsplus.com/'
));
Here’s how it is posted.
Some Additional Information you Should Know:
The user can easily revoke permissions with two clicks in his or her wall. You should heavily test what might happen if a user revoked one or more permissions that are vital for the proper functioning of your website, or even if the application is fully removed. This is important.
- In Application Settings you can remove the application entirely by clicking the x at the right side.
- You can remove permissions individually in the Granted Additional Permissions section.
5. Conclusion
While Facebook’s authentication capabilities are indeed useful, since so many people are on Facebook these days, using it as the only method of authentication in a site is not recommended. What about those who don’t have Facebook accounts? Are they not allowed to access your application? Thanks for reading!


Thanks for this, we are working on developing this for our users as an option to access their account on our end.
great tutorial rafael
idk why the facebook doesn’t load the creat app page and when didn’t give me the page of app id and secret
What happens If a user later decides to remove the application? How can we erase his records from the Database?
Hi Dimitree take a look a this:
http://wiki.developers.facebook.com/index.php/Post-Remove_Callback_URL
In a few words, you can define a callback url which will be called (in POST!!) when user uninstal your app. So at this url you can specify some database clean procedure.
Yari
have you tested it? I did and it’s not working to me, I receive the call to my Callback URL, but $_POST is empty always.
I’m not the only one with this problem, but I couldn’t find any solution.
Is it working the Post_Remove_Callback_URL in your application?
You have a typo error in this tutorial
after-
# If not, let’s add it to the database
if(empty($result)){
$query = mysql_query(“INSERT INTO users (oauth_provider, oauth_uid, username) VALUES (‘facebook’, {$user['id']}, ‘{$user['name']}’)”);
$query = msyql_query(“SELECT * FROM users WHERE id = ” . mysql_insert_id());
the second query should be
$query = mysql_query
the typo error is on line # 48
thanks, good tutorial
It was of great help
Thanks a bunch! – this tutorial saved my ass
Bravo! Finally! A tutorial I can understand, with examples that are easy to customize for my own needs. Awesome!
Awesome tutorial! Easy to understand and high class. Thanks Tutsplus!
I wonder if it is also possible saving the access token in Javascript SDK. There is no next and cancel parameter in Javascript SDK…hmmm…I don’t know how to do the same thing using Javascript SDK. Thanks for the PHP Tutorial.
looking for logout.php for facebook_login
I made it as a facebook application.But this is working for only owner of the application. when i try to access the application as another user through facebook , application is not returning the current user session.Please help me.
Hi, thanks for this facebook “app” anyway, its not really working. anyone got it working right? i got errors like a few others in here.
and if i just google chrom it just got to my redirect page and nothing happens.
hope some one would make something that really worked. everyone is asking for it, but not many got it working.
pls someine help.
Great post with simple code to authenticate users with Facebook Connect.
Thanks for sharing.
I got this error how to remove this “Firefox has detected that the server is redirecting the request for this address in a way that will never complete.This problem can sometimes be caused by disabling or refusing to accept cookies.”
How can we send send post if user is not logged in his facebook account
vicky says:
August 4, 2010 at 12:47 pm
I got this error how to remove this “Firefox has detected that the server is redirecting the request for this address in a way that will never complete.This problem can sometimes be caused by disabling or refusing to accept cookies.”
i got this prob also.. can someone try to fix this please…
Thanks a lot. Great tutorial
I am getting the same error with the redirecting request never completing. It started when I tried to get extended permissions, the login seemed to work fine.
Any help please?
It seems it is actually granting the permissions, but it doesn’t resolve properly when it gets to facebookuid or whatever it is.
It’s clearly an issue with your readers that your code is creating a loop. You have acknowledged it yourself in the comments and offered no solution. While I understand you did this off your own back and it has helped a little, you have left huge holes that, when combined with how severely lacking the facebook documentation is, leaves people that are trying to learn running round in circles. The forums are saturated with unanswered questions and the fact that there are seemingly so many wrong ways of doing something means it’s impossible to get an answer.
Can you please address the redirect issue? Otherwise, what’s the point in writing a tutorial? Inettuts is so frustratingly blase with some of their stuff, sometimes I wonder how much more harm than good this site does. Certainly puts me off a premium membership.
Seriously, can you address the redirect issue? I can’t do anything about it if I can’t even find what it is meant to be doing int the first place.
hi to all of you guys!
I get an error when I try to run my facebook application. I am new to PHP and would like to learn more on it.
And I am also using a free webhosting site.
Fatal error: Uncaught exception ‘Exception’ with message ‘Facebook needs the CURL PHP extension.’ in /www/../andoy/htdocs/php_test/facebook.php:4 Stack trace: #0 /www/..andoy/htdocs/php_test/index.php(5): require() #1 {main} thrown in /www/../andoy/htdocs/php_test/facebook.php on line 4
Thanks for any comment.
I’d appreciate it.
you need to install curl for php5:
sudo apt-get install curl libcurl3 libcurl3-dev php5-curl php5-mcrypt
Where do we type this?
in the ubuntu terminal
by the way.. thanks for the great tuts..
To those going on about the redirect loop:
The reason it’s looping is because there is no initial check to see if the user already has the permission you’re requesting for.
Just add an API call for the permission you’re checking. If it’s 0, then make the request.
It seems it is actually granting the permissions, but it doesn’t resolve properly when it gets to facebookuid or whatever it is.
header(“Location: {$url} “); is no longer working..
Hello
Is there a way to verify the response authenticity from Facebook in order to prevent someone posting back to my script with mangled GET values….
Maybe the session key or some sort of secret to be checked against actual FB application?
Thanks
Cristian
thanks a heap .. ive been looking all over the place for a decent tutorial to help me integrate facebook connect .. thanks again, your a legend!!
Header redirect won’t work anymore if you are integrating it to a canvas page of application.
Maybe, is there anyway of other redirections ?
I know this tutorial is a bit outdated and it’s not exactly the intent of this tutorial to do this, but can anyone tell me how I can modify this so that it redirects back to the facebook app itself rather than my website?
Every time I try to make it redirect back it just keeps bringing up the “log into facebook” page, despite having already given it permissions. Any help at all would be appreciated.
Why …… fields => ‘ current_location’ value not appear?
1. $uid = $facebook->getUser();
2. $api_call = array(
3. ‘method’ => ‘users.getinfo’,
4. ‘uids’ => $uid,
5. ‘fields’ => ‘uid, first_name, last_name, pic_square, pic_big, sex, current_location’
6. );
7. $users_getinfo = $facebook->api($api_call);
Hey!
Thanks a lot! this is a great, great tutorial, easy and very understandble.
It was so helpful for my application! thanks!
Muy buen tutorial! De lo mejor que he encontrado y bien explicado :)
Most amazing tutorial i’ve found, with such simple instructions. Thanks a ton for the perfect information for me to set up my site!
Thanks for the great tutorial. I am looking for such a tutorial for last 10 days. It really works. Thanks Again.
Thanks for this post, saved my hide man!
thanks for this tutorial
This worked very well. I used it in conjunction with Facebook register on the homepage of my website. I was able to get the UID from my own login. Is there a way to also get the email address of the Facebook user? I need to send that to our database so that the application they will be using in Facebook can show their Bizclickr.com content.
I added a $email variable and put it in the list for INSERTING into MySQL, but the field is empty. Is there another attribute that I need to introduce into the PHP page?
Thanks!
I get the following errors in Step 2.
1. Fatal error: Uncaught exception ‘Exception’ with message ‘Facebook needs the CURL PHP extension.’ in C:\wamp\www\helloPlane\facebook.php on line 4
2. Exception: Facebook needs the CURL PHP extension. in C:\wamp\www\helloPlane\facebook.php on line 4
Hey developers…
I’m thinking for those dudes who get an “there was an error” error message, i think this occurs when you change the SITE URL text field in the Facebook developer page,most probably your changes haven’t been propagated to all the servers…it does work after a while though
if you are using Linux, follow the instructions on the comments posted in the previous page: download the curl extension: apt-get install libcurl3
type that in the terminal.
or go here:
http://www.tildemark.com/programming/php/enable-curl-with-xampp-on-windows-xp.html
hope this helps…
all the best
Hi Friends,
I work According to you , But I got a Blank page with it’s URL pointing to : http://www.facebook.com/developers/login_error.php?app_id=188688331164433&connect=1&type=connect
why this ? Please Advise Where I wrong and reply me with your ideas immediately in my email :
anes(dot)pa(at)gmail(dot)com …
Thankfully,
Anes P.A
When i try to go to login_facebook.php as described in step 2, i get
“unexpected ‘{‘ at line 18″
this is right after “try”
Facebook have changed there ways of facebook connect, any chance of this tutorial being updated?
Thanks
I´m wondering the same thing.
Thanks in advance!
“If you are redirected to Facebook and requested for permission, we are on the right track.” – http://i273.photobucket.com/albums/jj226/stefek99/facebook-connect.png
Additionally: “On the connect tab, set the Connect URL” – no connect tab… :]
Probably some changes occurred. Update is necessary! :)
with id, username, first and last name, the URL to the user’s picture, and registered date
There are no such columns in the MySQL table definition provided :)
I want to grab user id when user accept my permission and store user id in database. anybody please help me!
“There might be another issue, where you see an error, like “Uncaught CurlException: 60: SSL certificate problem, verify that the CA cert is OK.” This happens because of the CURL settings. You’ll have to open facebook.php, find the makeRequest() method, and, inside the function, find this line: … I hate hacking libraries, but I haven’t found another way.”
Hi Rafael, thanks for the tutorial.
Regarding your solution for turning of cURL’s peer verification. The CURL_OPTS array in the Facebook class is a public static field, so it’s modifiable from your own code. if you notice in the makeRequest() method, Facebook uses whatever options are set in its CURL_OPTS array, then adds to them. So, this would achieve what you want:
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false;
$facebook = new Facebook(array(
‘appId’ => ‘YOUR_APP_ID’,
‘secret’ => ‘YOUR_APP_SECRET’,
‘cookie’ => true
));
Or, an even better solution which achieves better encapsulation would be to extend the Facebook class and override the constructor, setting your custom cURL options, like this:
class MyFacebook extends Facebook {
const APP_ID = ‘YOUR_APP_ID’
const APP_SECRET = ‘YOUR_APP_SECRET’
public function __construct() {
// Turn off SSL certificate checking
parent::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false;
parent::__construct(array(
‘appId’ => self::APP_ID,
‘secret’ => self::APP_SECRET,
‘cookie’ => true,
));
}
}
Then, you would instantiate your custom Facebook class and use that instead of the default one:
$facebook = new MyFacebook;
Fantastic Tutorial, But only one problem.
Every time anyone goes to http://leetlikes.com/login_facebook.php it just comes up with “There was an error”
How can I fix this?
Am having trouble logging out of the Facebook Connect.
I am destroying the session and logging out this way
$this->Session->destroy();
$this->redirect($this->Auth->logout());
am using cakephp.
when i logout of facebook.com
and still click facebook login. its still logs in – even though am logged out on facebook.com
Hey Harsha, I think you just need to “start session” before you “destroy session”. Hope that works. (worked for me)
hi, i would like to add my web page to Facebook as an application but i have a database for my users how can i integrate it or add/register facebook users or signed them automatically as an registered users so they can access my site
thank you
Hi there,
I must say this is the Best tutorial of all the Facebook App development.
But have a problem, After executing the statement
$facebook->api(‘/’.$uid.’/feed’, ‘post’, array(‘message’ => ‘Saying hello from my Facebook app!’));
in the http://www.myserver.com/thanks.php
In the browser is redirected to this page. And it is “NOT” going back to Facebook App interface.
Did I do something wrong ? Or do I have to do anything to redirect back to the Facebook App interface?
Thanks – Ajeesh
Hi guys, Facebook has updated its API and this tutorial is now outdated, any plans to update it? :)