The type of sites that almost every Internet user has signed up for are Social Networks, and the most popular of these Social Networks is Facebook. People are always logged-in to their favorite Social Network. The best part about these Social Networking sites is that they facilitate a feature that allow other programs or sites to communicate with their Servers to Retrieve information about you through their API. Using this feature opens up many possibilities one of which is Authentication – The Act of confirming one’s Identity. You can easily Login one of your users by just looking at who your user is logged-in as on Facebook. Facebook Login is common all around the web. To give you some ideas on web design online just visit Web Design Cardiff.
Many sites use Facebook Login, for example: Vimeo, Khan Academy, Tech Crunch, PasteBin
KhanAcademy.org uses Facebook Login to authenticate their users
This is a little bit of hassle for the developer but it enhances User Experience by simplifying the Login procedure as it doesn’t require your users to remember Login details.
Are you Ready?
To continue this tutorial you must know of HTML, PHP, MySQL and a little bit of CSS just to make things look nice. (Javascript based features are not included for the sake of simplicity)
You must understand what Sessions are and you must also understand how to use MySQL with PHP. We are going to use the MySQLi PHP Extension for this tutorial.
Setup Facebook Application
We must let Facebook know that our website will be communicating with their servers. To do that we have to setup a Facebook Application and we also have to make sure we have a website development company helping us out…
- Login to your Facebook account
- Go to this address: https://developers.facebook.com/apps
- Click this button on the top right corner of the page:
- Fill in the “App Name” Field with your site’s name
- Fill in the other Information…
- Make sure you add your website domain with both www. and without…
- Don’t forget the slash(/) at the end of the site URL..
- Remember to disable Sandbox Mode…
- Copy down these two pieces of information somewhere else, we will need it later and be sure to show it to Absolutely No One especially the “App Secret“. Anyone else knowing these may pose a Security Threat.
- Now Save Changes….
CONGRATULATIONS! You have finished Setting Up your Facebook app!
A Few things to note
- Facebook will only accept Logins from the URLs provided.
- You may(for testing purposes) change the Site URL to “http://localhost/fb_login/“
and the App Domains to just “localhost“
- If you don’t want to change the settings then all testing must be done on the server that is running at the provided Domain & URL
Prepare a Basic site with a Simple Login System
For your convenience we have prepared one for you, so you don’t have to waste your time making a simple login System
Caution: Do not follow this as a good example for a Login System. This is very Basic and has many Security holes. The code is only for testing and understanding the Facebook Login procedure.
Instructions
- Copy and paste the files inside the Zip folder to a test directory on your server
- Make a database in your MySQL server named “fb_login“
- Execute this piece of SQL inside your fb_login Database. This creates a table named “users” and fills it with example data…
1 |
CREATE TABLE IF NOT EXISTS `users` ( |
2 |
`id` int (10) NOT NULL AUTO_INCREMENT, |
3 |
`username` varchar (100) NOT NULL , |
4 |
` name ` varchar (100) NOT NULL , |
5 |
`email` varchar (100) NOT NULL , |
6 |
` password ` varchar (200) NOT NULL , |
8 |
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; |
10 |
INSERT INTO `users` (`id`, `username`, ` name `, `email`, ` password `) VALUES |
11 |
( NULL , 'awesome' , 'Awesome Person' , 'awesome-guy@my-awesome-website.com' , 'awesome' ), |
12 |
( NULL , 'amazing' , 'Amazing Person' , 'amazing-guy@my-awesome-website.com' , 'amazing' ) |
- Execute this piece of SQL, but this time replace the fields with your
- Any Username you choose
- Name
- Email address that you used on Facebook
- Any password of your own choice
1 |
INSERT INTO `users` VALUES |
4 |
'A USER NAME OF YOUR CHOOSING' , |
6 |
'YOU EMAIL ADDRESS THAT YOU USED ON FACEBOOK' , |
7 |
'A PASSWORD OF YOUR CHOOSING' |
- Go back to your test Directory and open the file named “config.php” inside your favorite code Editor
- Edit this line according to your MySQL Server settings.
1 |
$db = new mysqli( "HOST" , "USERNAME" , "PASSWORD" , "fb_login" ); |
For Example:
1 |
$db = new mysqli( "localhost" , "root" , "root" , "fb_login" ); |
- Save the file.
Now open the URL to your test directory(in my case: http://localhost/fb_login/) in your browser. If you have followed all the instructions correctly then you should be greeted by a page that looks like this:
Test Site Homepage
Test the site login by either using the details you used in Step#4 of the Instructions or:
Username: awesome
Password: awesome
After testing everything, you will notice that the “Login with Facebook” button doesn’t do anything. That button is linked to a file named “login_facebook.php“, this file is left blank intentionally so that you can follow this tutorial and code the Facebook Login system yourself.
A Little overview on what all the other files do:
- index.php: The Main Page(aka. Homepage).
- login_normal.php: The script that handles the standard login. It check if you have properly written your Username & Password, then if you have, it tries to match the password you have written with the password stored in the database. If both match then it sets a session variable named $_SESSION[“user”] with the id of the user who logged in.
- logout.php: unsets the variable $_SESSION[“user”] in turn logging out the user.
- profile.php: Simply gets information from the database according to the id set inside $_SESSION[“user”] and displays it.
- config.php: Initializes the MySQL Database Connection and stores the connection handle in a variable named $db
Facebook Login
So open the login_facebook.php file in your Code Editor of choice then start the session, include the database connection file and set the App ID, App Secret and Redirect URI into variables as so:
5 |
$app_secret = "YOUR APP SECRET" ; |
6 |
$app_id = "YOUR APP ID" ; |
7 |
$redirect_uri = urlencode( "URL TO YOUR login_facebook.php SCRIPT" ); |
Example Variable values:
1 |
$app_secret = "dca0448bca2a4445c0b69cef34bfe09d" ; |
2 |
$app_id = "392754540811317" ; |
3 |
$redirect_uri = urlencode( "http://localhost/fb_login/login_facebook.php" ); |
Now observe this diagram with attention:
Diagram giving an Overview of the whole Facebook Authentication Process
So lets assume the first step is complete, but your user isn’t going anywhere yet. We must redirect the user to the Facebook Login Dialog. So what exactly is this so called Dialog?
This is the so called Dialog
Facebook OAuth Dialog
This can be shown to the users by redirecting them to a URL that looks like this:-
https://www.facebook.com/dialog/oauth?client_id={YOU APP ID}&redirect_uri={FACEBOOK LOGIN HANDLING URL}
Remember Step#6 of Setup Facebook Application? Yes, that is where you will get your “App ID”. The “FACEBOOK LOGIN HANDLING URL” is the URL to the PHP script that will handle the Facebook Login.
An Example URL to invoke the Facebook OAuth Dialog:-
https://www.facebook.com/dialog/oauth?client_id=508015629253444&redirect_uri=http://localhost/fb_login/login_facebook.php
You could be a Object Oriented Guru but as this tutorial was intended for Beginners so we will use the normal, procedural method. So lets write up a Function to redirect our users…
2 |
global $app_secret , $app_id , $redirect_uri ; |
This URL alone is enough for getting your user’s First Name, Last Name and other basic information, but no we need a little more then this. We need the user’s email address in order to authenticate a user into our site. So to let Facebook know we will be needing the email address, we must send a third parameter called “scope“. The Scope parameter contains a comma separated list of special Permissions like in our case: “scope=email“. (For the full list of permission that can be requested click here)
Just as a security measure, a fourth URL parameter named “state” should be sent. This state should be a randomly generated string. The string should also be stored in a session variable temporarily so that when the string will be passed back to your site after a successful authentication in the “state” parameter once again you can match it with the session variable to confirm that the request was not a result of a Cross-Site Request Forgery.
So here is the revised dialog() function that includes the scope parameter and also sends and stores the state parameter and a Random string generator function:-
1 |
function generate_state(){ |
2 |
return md5(uniqid(rand(),TRUE)); |
6 |
global $app_secret , $app_id , $redirect_uri ; |
8 |
$state = generate_state(); |
9 |
$_SESSION [ "state" ] = $state ; |
Calling calling the dialog() function will start redirecting your user to the OAuth Dialog but if we don’t add any logic then your users will be stuck in a Infinite Redirection Loop. To start coding the logic in, you must know what parameters are passed back to your site when one of the two buttons are clicked. Here is a Diagram:-
URL Parameter that are sent back
So to check if your user clicked “Okay” we can check if the “code” parameter is set. To check if the user clicked “Cancel” we can check if the parameter “error” is set, and if neither is set then it must mean the page is being requested for step#1 of the authentication process, that’s when we can call the dialog() function. So in code it should look something like:-
1 |
if (isset( $_REQUEST [ "error" ])){ |
2 |
header( "location: index.php" ); |
3 |
} elseif (isset( $_REQUEST [ "code" ])){ |
6 |
if (isset( $_REQUEST [ "state" ]) && $_REQUEST [ "state" ]== $_SESSION [ "state" ]){ |
7 |
$access_token = get_access_token(); |
8 |
$data = getData( $access_token ); |
10 |
authenticate_user( $data [ "email" ]); |
You could do a lot of fancy things when the user clicks the “Cancel” button like: you can Display out the error, error_reason & error_description parameters or you could save it in a session variable and show which button to click on the homepage, but for now we will just redirect the user back to the homepage.
In the code block on the middle(the one you were asked to temporarily ignore), the one which executes when the user clicks “Okay” – the passed back “state” value and the value stored in $_SESSION[“state”] are matched to protect against Cross-Site Request Forgery. Also, three new functions are introduced that we didn’t declare yet. They are: get_access_token(), getData() and authenticate_user().
Function: get_access_token()
Lets start understanding and writing the get_access_token() function. First we need to understand what a Access Token is. Access Tokens are strings which is used as a temporary passcode to be able to communicate with the Facebook servers. It has to be sent as a parameter of every request we send to Facebook’s graph API as such:
https://graph.facebook.com/me/friendlist?access_token=CAACEdEose0cBADBeKF7456meGvgHGK7ZAetsoNnLTXZBxzsVpz5dvilZCN3ACXrXZAuvuDbA7aWjdLeOXVy5enZCZAUmNa9VmZBwwvVfZBoZBzIXBazyuBn41ctuQeSnCI9an420ii5tV83R9vZBUFmxjmM4sMZCoAsUvMnHiNOHXqOcgZDZD
Yes! I know, that’s quite a long string! but that is an example of an access token. Each access_token is valid for only about 1 or 2 hours. Every new Access Token is unique and they are binded to a Specific user using a specific Application at a specific time frame.
Note: Every request to the Facebook API requiring an access token must be done over a HTTP Secure(https://) Connection.
To obtain an access_token we have to trade the value of the “code” parameter. This can be done by sending a get request to an end-point and passing the code as a parameter. Example:-
https://graph.facebook.com/oauth/access_token?client_id=508015629253444&redirect_uri=http://localhost/fb_login/login_facebook.php&client_secret=[THE SECRET STRING YOU COPIED DOWN FROM HERE]&code=[THE VALUE OF THE CODE PARAMETER]
Requesting this URL will return a String that looks like a query string of an URL. Example:-
access_token={access-token}&expires={seconds-til-expiration}
Lets wrap this all up into a function:
1 |
function get_access_token(){ |
2 |
global $app_secret , $app_id , $redirect_uri ; |
4 |
$code = $_REQUEST [ "code" ]; |
6 |
$call = file_get_contents ( "https://graph.facebook.com/oauth/access_token?client_id=$app_id&redirect_uri=$redirect_uri&client_secret=$app_secret&code=$code" ); |
We could have used the PHP cURL Library but to keep it simple, we have not used that.
The parse_str() function converts a query string into variables. Example:
1 |
parse_str ( "access_token=an_access_token&expires=3000" ); |
will output:
an_access_token
3000
Function: getData()
So we got our Access Token, what’s next? Now we have to use this Access Token to get information about the user, especially the email address. We can do this by calling the “/me” from the Facebook Graph API. Example:-
https://graph.facebook.com/me?access_token=[ACCESS TOKEN]
The response from Facebook would be something like:-
(This example response was the result of requesting “/me” logged-in as me)
{
"id": "100000299160491",
"name": "Omran Jamal",
"first_name": "Omran",
"last_name": "Jamal",
"link": "http://www.facebook.com/Omran.Jamal",
"username": "Omran.Jamal",
"gender": "male",
"email": "o.jamal97@gmail.com",
"timezone": 6,
"locale": "en_US",
"verified": true,
"updated_time": "2013-05-11T11:40:48+0000"
}
to be more Specific about returning only email and name we can add a “fields” parameter example:-
https://graph.facebook.com/me?fields=name,email&access_token=[ACCESS TOKEN]
this is will return(The “id” field is mandatory, so it will be returned anyway):-
{
"name": "Omran Jamal",
"email": "o.jamal97@gmail.com",
"id": "100000299160491"
}
The responses from the Graph API are in JSON format, thankfully PHP has built-in JSON parsing functions so we can manipulate them like normal PHP Arrays. Here is the getData() function:-
1 |
function getData( $access_token ){ |
2 |
$raw = file_get_contents ( "https://graph.facebook.com/me?fields=name,email&access_token=$access_token" ); |
3 |
$array = json_decode( $raw ,TRUE); |
Function: authenticate_user()
Now that we got our user’s Facebook email address all that’s left to do is to write a function that will match the email address with the database and set the session variable with the corresponding user’s id…
1 |
function authenticate_user( $email ){ |
4 |
$query = $db ->query( "SELECT id FROM users WHERE email='" . $email . "'" ); |
5 |
$array = $query ->fetch_assoc(); |
6 |
if ( $query ->num_rows==1){ |
7 |
$_SESSION [ "user" ] = $array [ "id" ]; |
8 |
header( "location: index.php" ); |
10 |
header( "location: index.php" ); |
If the email doesn’t match with any in the Database the user is simply redirected back to the homepage.
The full “login_facebook.php” file
5 |
$app_secret = "YOUR APP SECRET" ; |
6 |
$app_id = "YOUR APP ID" ; |
7 |
$redirect_uri = urlencode( "URL TO YOUR login_facebook.php SCRIPT" ); |
9 |
function generate_state(){ |
10 |
return md5(uniqid(rand(),TRUE)); |
14 |
global $app_secret , $app_id , $redirect_uri ; |
16 |
$state = generate_state(); |
17 |
$_SESSION [ "state" ] = $state ; |
24 |
function get_access_token(){ |
25 |
global $app_secret , $app_id , $redirect_uri ; |
27 |
$code = $_REQUEST [ "code" ]; |
29 |
$call = file_get_contents ( "https://graph.facebook.com/oauth/access_token?client_id=$app_id&redirect_uri=$redirect_uri&client_secret=$app_secret&code=$code" ); |
35 |
function getData( $access_token ){ |
36 |
$raw = file_get_contents ( "https://graph.facebook.com/me?fields=name,email&access_token=$access_token" ); |
37 |
$array = json_decode( $raw ,TRUE); |
42 |
function authenticate_user( $email ){ |
45 |
$query = $db ->query( "SELECT id FROM users WHERE email='" . $email . "'" ); |
46 |
$array = $query ->fetch_assoc(); |
47 |
if ( $query ->num_rows==1){ |
48 |
$_SESSION [ "user" ] = $array [ "id" ]; |
49 |
header( "location: index.php" ); |
51 |
header( "location: index.php" ); |
55 |
if (isset( $_REQUEST [ "error" ])){ |
56 |
header( "location: index.php" ); |
57 |
} elseif (isset( $_REQUEST [ "code" ])){ |
59 |
if (isset( $_REQUEST [ "state" ]) && $_REQUEST [ "state" ]== $_SESSION [ "state" ]){ |
60 |
$access_token = get_access_token(); |
61 |
$data = getData( $access_token ); |
63 |
authenticate_user( $data [ "email" ]); |
GREAT! Test out the Site by going to the test Directory address (eg. http://localhost/fb_login/). Then click on the “Login with Facebook” Button. If you have followed this tutorial smoothly and if the email address that you gave in Step#4 of the Instructions and the email address that you use on Facebook matches then you should see that you have been logged in to your site and the main navigation now has a “My Profile” link.
“My Profile” Page
Conclusion
I hope after reading this tutorial you have gotten the basic principle of how the Facebook Authentication works. If you did, then I bet you can customize this basic code to suit your needs and make almost any type of login system work with Facebook. You may try and implement this code in an Object Oriented Style so that you can reuse the Facebook Login system in as many projects as you want with ease, but for now that’s all..:)
Stay tuned to w3programmers for more tutorials from me on Facebook Application Development
Hi, I am Omran Jamal from Bangladesh, a Student of A-Level, and an Intern at Techbeeo. Though young, I am very enthusiastic about Computers. Taught myself how to code when I was 12 and been coding ever since.