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!



RoyalSlider – Touch-Enable ... only $12.00 
Corect: header(“Location: .$login_url”);
Thank you btw! I implement both facebook and Twitter log in from your tuts.
I would like share few thoughts about Facebook Authentication here at http://lookmywebpage.com/api/facebook/facebook-authentication/
get to know how use google to authenticate users:
http://lookmywebpage.com/api/google/authenticate-users-using-google-open-id/
Thank you both your new threads and The author of the post. this is awesome with demo source.
Hey I have a quick session. Let’s say I have a user who registers for my site normally (with email and password).
Then they logout and clear all their cookies.
Next time they come to the site they click “login with Facebook”. Is the only way to really detect and link the 2 accounts by comparing their email on Facebook and the other they registered with on my site previously?
Or is there a better way of going about this. I know the chances are small of this happening, but I was just wondering if anyone has run into this problem or have a solution for it.
Great tutorial!
if the cookie and session is clear and the user is trying to login to your site using facebook, he will be redirected to login dialog of facebook and the step repeats. a new code is generated and a new access token. otherwise you need to ask for offline access in permissions or scope
Very insightful tutorial … does more justice to the subject than the facebook documentation itself … #ManyThanks
Very useful tutorial, Rafael!
I would like to know how to do this using a popup window that closes before you login to facebook…. Can u gimme a little help?
Just to add an update which might help others, the Facebook.php file was changed in May 2011 to use access tokens instead of internal sessions so you will need to make a change to the method request on line 12 of the script above.
From GitHub (21st May 2011):
Updated to use access tokens instead of sessions internally. This implies many changes to the storage scheme, which is why it is a major revision. Upgrading from a previous version should change most getSession() calls to getUser() which returns a User’s ID instead of a session object. See: https://developers.facebook.com/blog/post/503
Change Line 12:
$session = $facebook->getSession();
to
$session = $facebook->getUser();
Superb post by the way, it has opened up so many useful data capture opportunities.
Thanks a ton for this blog !
the oauth for facebook has been updated.. could you please update this post?
Please update this to work with the new php-sdk 3.1!
Hi ,
I have doubt regarding the logout.
I have used $facebook->getLogoutUrl(); this url to logout.
But it is not logout the facebook.
Please suggest me some solution.
ummm esta bien
hello, i need some help,
i was apply the script, it’s so Good,
but i wanna know how to do
* Request for Permission
– Access my basic information
– Send me email
to appear both of them together
bcs till now:
first it’s appear:
– Access my basic information & i click allow & after it’s appear – Send me email & i click allow
this mean i do to allow instead one allow
I need communica tion so I neet my account accept in several provide.
but i wanna know how to do
* Request for Permission
– Access my basic information
– Send me email
The facebook users email will not be returned unless you ask for it through “extended permissions”.
In order to request extended permission for “email” I exchangended the line:
$login_url = $facebook->getLoginUrl();
with:
$login_url = $facebook->getLoginUrl(array(‘scope’ => ‘email’));
The email should now be part of the array returned from facebook – $user[email] in this example.
Hope this helps!
Hello!
I can create twitter follower easily with this tutorial: http://net.tutsplus.com/tutorials/php/how-to-authenticate-users-with-twitter-oauth/comment-page-1/
$twitteroauth->post(‘friendships/create’, array(‘screen_name’ => ‘faelazo’));
I’d like do this on Facebook (just not follow, but like). I try it, but failed.
How can I do this?
Thanks,
roxyboy
Epic tutorial .. nice
Nice Post men :D but i have a question How i can put toguether post on wall and Extended Permissions ¿? because i try to put toguether and when i accept the permissions the browse stay loading and then show me a error that say that my page have a redirect loop how i can fix it ¿? in advance thank you very much
hey i am trying step 2 and i have changed the getSession to getUser and then when i am using it and it is giving a blank page. Pls help !!!!!!!!!!!!!!!!!!!!!
can any help me by sending the code in a synchronized way i m stuck at extended permission pls that will be a big help
hi,
i have the following error:
Parse error: syntax error, unexpected T_DNUMBER in /home/ikbenex/public_html/login_facebook.php on line 3
line 3 in my .php:
require(“facebook.php”);
who can help me with a solution?
FACEBOOK AUTHENTICATION, AUTHORIZATION and HOW TO GET ACCESS_TOKEN_CODE and finally get the Friends List
These Steps will do the following
1. Register You App or(Java Class if it is only one Class) with Face Book also add some redirect URL.
2. Once you register your App it will give you App Id and client_secret.
3. Once the user is logged in his Facebook Account the URL given below
will prompt the user for the permission. If the user is not logged in It will ask the person to login and ask his permission to Install and than ask the permission to Allow.
Once the User allows it, it will redirect the user to the redirect URL which you have specified at the time of App registration (see point1)
http://www.facebook.com/dialog/permissions.request?_path=permissions.request&app_id=135940433179912&redirect_uri=http%3A%2F%2Fww2.cox.com%2Fmyconnection%2Farizona%2Fhome.cox&display=page&response_type=code&fbconnect=1&perms=user_photos%2Cuser_videos%2Cemail%2Cpublish_stream&from_login=1
4. Once A User Accepts the Permissions it will redirect the user to the redirect url as given below.
http://ww2.cox.com/myconnection/arizona/home.cox?code=AQClfi20blwSnrsvDh863M37GY7vZcP2YwIv6_eHc1EwIO-64IafFt_pWzMxo0wV-oOkoePuNsq0Gq7DzAcRBLCic2kpIZRmnklWgFPQZeTWUlob5nK2jOGCMkPuuy8r0JVfWrzlqOqm-LNDMrlxn8LnbaZO9ZymmB665Ink7vfLDVNPgYT0Zt4n9oXpy_H0nsEi2lQm9rcy-1kC1hU9v83m#_=_
copy everything after the CODE from your redirect url and add to the following URL along with your APP_ID, RedirectURL and client_secret
https://graph.facebook.com/oauth/access_token?client_id=135940433179912&redirect_uri=http://ww2.cox.com/myconnection/arizona/home.cox&client_secret=45fac9f6ef91c55a5c9f4e577cfbff66&code=AQBmo3cxLTl11qJNthBuHKUe5Alz9gBvFCBWPkW9zOtcB-z9hZG39QUM3r-SegkXHgFhkWj2FOt4aXiOz4yg8eiEmORka3W52NlEH7oChFBALn-TyZD5JCqAEOmJOxFq616nbgsSeMFUaGQ-tiWemJNm4s0sblwWVUts0JhGf77O9Eb1GYOI9T5wYVfxiz531y7ljHzeVVADsrw5nH6OBrnb#_=_
5. Once you hit this url it will give you your ACCESS_TOKEN as given below.
access_token=AAAB7oxk69QgBADXi9mdXXHsm0ATzNzSZAbce0YNME8wL1qWUT2YEMyDAMq6DyNSO7Q5mblcKhCo4BVS9enXKo19EKKP6fSHmpenacFvo6W1HaZCc6o&expires=6603
6. Add this Above token to this URL and it will give you all his inbox messages.
https://graph.facebook.com/me/friends?access_token=AAAB7oxk69QgBADXi9mdXXHsm0ATzNzSZAbce0YNME8wL1qWUT2YEMyDAMq6DyNSO7Q5mblcKhCo4BVS9enXKo19EKKP6fSHmpenacFvo6W1HaZCc6o&expires=6603
I hope This Will help Many, Please use your AppID, Client_Secret, and Authorizationcode and Access_token
Thanks & Regards
Ajay Mahindru
Any plans to update this since FB has changed the way they authenticate users for outside sites?
hello am having a big problem with facebook connect, i installed the sa mod for it on my smf forum but facebook has changed the app setup from what you have up here, when i try to connect with facebook on my site it takes me to my facebook app page and shows option to install instead of allow, and when i click on install, it asks for permision to post, then i say yes, then it takes me back to my website and says error no connection to facebook found.
please i need the present steps on how to do this….thanks alot.