Saturday, October 9, 2021

Login with Facebook using PHP

 Nowadays the web users are not interested in filling a big form for registration on the website. The short registration process helps to get more subscribers to your website. 

Login with Facebook is a quick and powerful way to integrate registration and login system on the website. Facebook is the most popular social network and most of the users have a Facebook account. 

Facebook Login allows users to sign in to your website using their Facebook account credentials without sign up on your website.

PHP SDK allows accessing the Facebook API from the web application. You can easily implement the Login with Facebook account using Facebook SDK for PHP. This tutorial will show how you can implement user login and registration system with Facebook using PHP and store the user profile data into the MySQL database. Our example Facebook Login script uses Facebook PHP SDK v5 with Facebook Graph API to build Facebook Login system with PHP and MySQL.

To get started with the latest version of Facebook SDK v5.x, make sure your system meets the following requirements.

  • PHP version should be 5.4 or greater.
  • The mbstring extension should be enabled.

Before you begin to integrate Login with Facebook using PHP, take a look the files structure.

facebook_login_php/
├── config.php
├── index.php
├── logout.php
├── User.class.php
├── facebook-php-graph-sdk/
├── images/
│   ├── fb-login-btn.png
└── css/
    └── style.css

Create Facebook App

To access Facebook API you need to create a Facebook App and specify the App ID & App Secret at the time of calling the Facebook API. Follow the step-by-step guide to create Facebook App and generate App ID & Secret in the Facebook Developers Dashboard.

  • Go to the Facebook for Developers page and log in with your Facebook account.
  • Click the My Apps link at the top navigation bar and select Add New App.
    • Enter the Display Name and Contact Email.
    • Click on the Create App ID button.
    • You will be redirected to the App Dashboard.
  • Navigate to the Settings » Basic page.
    • Specify the App Domains and select the Category of your App.
    • Click the Save Changes.
  • Navigate to the Add a Product page by clicking the PRODUCTS(+) link at the left navigation menu panel.
    • Select Facebook Login to Set Up.
    • Select Web as the App platform.
    • Enter the Site URL and Save.
  • Navigate to the Facebook Login » Settings page.
    • In the Valid OAuth Redirect URIs field, enter the Redirect URL.
    • Click the Save Changes.

Go to the Settings » Basic page, note the App ID and App Secret. This App ID and App secret allow you to access the Facebook APIs.

create-facebook-developer-app-id-secret-codexworld

Note that: The App ID and App secret need to be specified in the script at the time of Facebook API call. Also, the Valid OAuth Redirect URIs must be matched with the Redirect URL that specified in the script.

Get the Profile Link and Gender

To retrieve the user’s Facebook timeline link and gender, you need to submit a request for user_link and user_gender permissions.

  • Go to the App Review » Permissions and Features page.
  • Request for user_link and user_gender permissions and submit the required information.
    facebook-user-profile-link-gender-permissions-request-codexworld

Once the review process is completed and approved by the Facebook, you will be able to get the user profile link and gender from the Facebook Graph API.

Do you want a detailed guide on Facebook App creation? Go through this guide to create Facebook Developer App and get the App ID & App secret.

Create Database Table

To store the user’s profile information from Facebook, a table needs to be created in the database. The following SQL creates a users table with some basic fields in the MySQL database to hold the Facebook account information.

CREATE TABLE `users` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `oauth_provider` enum('facebook','google','twitter','') COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
 `oauth_uid` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `first_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `last_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `gender` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
 `picture` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
 `link` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Facebook SDK for PHP

The facebook-php-graph-sdk/ directory contains the latest version (v5) of Facebook SDK for PHP. You don’t need to download it separately, all the required files of Facebook PHP SDK v5 are included in our Facebook Login PHP source code.

User Class (User.class.php)

The User class handles the database related operations (connect, insert, and update) using PHP and MySQL. It helps to connect to the database and insert/update Facebook account data in the users table.

  • __construct() – Connect to the MySQL database.
  • checkUser() – Insert or update the user profile data based on the OAuth provider and ID. Returns the user’s account data as an array.
<?php 
/*
 * User Class
 * This class is used for database related (connect, insert, and update) operations
 * @author    CodexWorld.com
 * @url        http://www.codexworld.com
 * @license    http://www.codexworld.com/license
 */

class User {
    private 
$dbHost     DB_HOST;
    private 
$dbUsername DB_USERNAME;
    private 
$dbPassword DB_PASSWORD;
    private 
$dbName     DB_NAME;
    private 
$userTbl    DB_USER_TBL;
    
    function 
__construct(){
        if(!isset(
$this->db)){
            
// Connect to the database
            
$conn = new mysqli($this->dbHost$this->dbUsername$this->dbPassword$this->dbName);
            if(
$conn->connect_error){
                die(
"Failed to connect with MySQL: " $conn->connect_error);
            }else{
                
$this->db $conn;
            }
        }
    }
    
    function 
checkUser($data = array()){
        if(!empty(
$data)){
            
// Check whether the user already exists in the database
            
$checkQuery "SELECT * FROM ".$this->userTbl." WHERE oauth_provider = '".$data['oauth_provider']."' AND oauth_uid = '".$data['oauth_uid']."'";
            
$checkResult $this->db->query($checkQuery);
            
            
// Add modified time to the data array
            
if(!array_key_exists('modified',$data)){
                
$data['modified'] = date("Y-m-d H:i:s");
            }
            
            if(
$checkResult->num_rows 0){
                
// Prepare column and value format
                
$colvalSet '';
                
$i 0;
                foreach(
$data as $key=>$val){
                    
$pre = ($i 0)?', ':'';
                    
$colvalSet .= $pre.$key."='".$this->db->real_escape_string($val)."'";
                    
$i++;
                }
                
$whereSql " WHERE oauth_provider = '".$data['oauth_provider']."' AND oauth_uid = '".$data['oauth_uid']."'";
                
                
// Update user data in the database
                
$query "UPDATE ".$this->userTbl." SET ".$colvalSet.$whereSql;
                
$update $this->db->query($query);
            }else{
                
// Add created time to the data array
                
if(!array_key_exists('created',$data)){
                    
$data['created'] = date("Y-m-d H:i:s");
                }
                
                
// Prepare column and value format
                
$columns $values '';
                
$i 0;
                foreach(
$data as $key=>$val){
                    
$pre = ($i 0)?', ':'';
                    
$columns .= $pre.$key;
                    
$values  .= $pre."'".$this->db->real_escape_string($val)."'";
                    
$i++;
                }
                
                
// Insert user data in the database
                
$query "INSERT INTO ".$this->userTbl." (".$columns.") VALUES (".$values.")";
                
$insert $this->db->query($query);
            }
            
            
// Get user data from the database
            
$result $this->db->query($checkQuery);
            
$userData $result->fetch_assoc();
        }
        
        
// Return user data
        
return !empty($userData)?$userData:false;
    }
}

Site Settings and API Configuration (config.php)

The database settings and Facebook API configuration constant variables are defined in the config.php file.
Database Constants:

  • DB_HOST – Specify the database host.
  • DB_USERNAME – Specify the database username.
  • DB_PASSWORD – Specify the database password.
  • DB_NAME – Specify the database name.
  • DB_USER_TBL – Specify the table name where the user’s account data will be stored.

Facebook API Constants:

  • FB_APP_ID – Specify the Facebook App ID.
  • FB_APP_SECRET – Specify the Facebook App Secret.
  • FB_REDIRECT_URL – Specify the Callback URL.

Call Facebook API:

  • The PHP SDK library is used to connect with Facebook API and working with OAuth client.
<?php
/*
 * Basic Site Settings and API Configuration
 */

// Database configuration
define('DB_HOST''MySQL_Database_Host');
define('DB_USERNAME''MySQL_Database_Username');
define('DB_PASSWORD''MySQL_Database_Password');
define('DB_NAME''MySQL_Database_Name');
define('DB_USER_TBL''users');

// Facebook API configuration
define('FB_APP_ID''Insert_Facebook_App_ID');
define('FB_APP_SECRET''Insert_Facebook_App_Secret');
define('FB_REDIRECT_URL''Callback_URL');

// Start session
if(!session_id()){
    session_start();
}

// Include the autoloader provided in the SDK
require_once __DIR__ '/facebook-php-graph-sdk/autoload.php';

// Include required libraries
use Facebook\Facebook;
use Facebook\Exceptions\FacebookResponseException;
use Facebook\Exceptions\FacebookSDKException;

// Call Facebook API
$fb = new Facebook(array(
    'app_id' => FB_APP_ID,
    'app_secret' => FB_APP_SECRET,
    'default_graph_version' => 'v3.2',
));

// Get redirect login helper
$helper $fb->getRedirectLoginHelper();

// Try to get access token
try {
    if(isset($_SESSION['facebook_access_token'])){
        $accessToken $_SESSION['facebook_access_token'];
    }else{
          $accessToken $helper->getAccessToken();
    }
} catch(FacebookResponseException $e) {
     echo 'Graph returned an error: ' $e->getMessage();
      exit;
} catch(FacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' $e->getMessage();
      exit;
}

Note that: You’ll find the App ID and App Secret on your Facebook App settings page.

Login & Get Facebook Account Data (index.php)

In this file, the Facebook API authentication process is handled using PHP.

  • Initially, the authentication URL is generated using getLoginUrl() method of login helper class and Facebook Sign-in button is displayed on the web page.
  • If the user authenticates with their Facebook account, the following happens:
    • The profile information is retrieved from the Facebook account using Facebook Graph API.
    • The account data is inserted into the database using checkUser() function of User class.
    • The user’s account info is stored in the SESSION.
    • The Facebook profile details (Name, First name, Last name, Email, Gender, Picture, and Profile link) is displayed on the webpage.
    • Also, the Logout link is generated using getLogoutUrl() method of the login helper class.
<?php
// Include configuration file
require_once 'config.php';

// Include User class
require_once 'User.class.php';

if(isset($accessToken)){
    if(isset($_SESSION['facebook_access_token'])){
        $fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
    }else{
        // Put short-lived access token in session
        $_SESSION['facebook_access_token'] = (string) $accessToken;
        
          // OAuth 2.0 client handler helps to manage access tokens
        $oAuth2Client $fb->getOAuth2Client();
        
        // Exchanges a short-lived access token for a long-lived one
        $longLivedAccessToken $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']);
        $_SESSION['facebook_access_token'] = (string) $longLivedAccessToken;
        
        // Set default access token to be used in script
        $fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
    }
    
    // Redirect the user back to the same page if url has "code" parameter in query string
    if(isset($_GET['code'])){
        header('Location: ./');
    }
    
    // Getting user's profile info from Facebook
    try {
        $graphResponse $fb->get('/me?fields=name,first_name,last_name,email,link,gender,picture');
        $fbUser $graphResponse->getGraphUser();
    } catch(FacebookResponseException $e) {
        echo 'Graph returned an error: ' $e->getMessage();
        session_destroy();
        // Redirect user back to app login page
        header("Location: ./");
        exit;
    } catch(FacebookSDKException $e) {
        echo 'Facebook SDK returned an error: ' $e->getMessage();
        exit;
    }
    
    // Initialize User class
    $user = new User();
    
    // Getting user's profile data
    $fbUserData = array();
    $fbUserData['oauth_uid']  = !empty($fbUser['id'])?$fbUser['id']:'';
    $fbUserData['first_name'] = !empty($fbUser['first_name'])?$fbUser['first_name']:'';
    $fbUserData['last_name']  = !empty($fbUser['last_name'])?$fbUser['last_name']:'';
    $fbUserData['email']      = !empty($fbUser['email'])?$fbUser['email']:'';
    $fbUserData['gender']     = !empty($fbUser['gender'])?$fbUser['gender']:'';
    $fbUserData['picture']    = !empty($fbUser['picture']['url'])?$fbUser['picture']['url']:'';
    $fbUserData['link']       = !empty($fbUser['link'])?$fbUser['link']:'';
    
    // Insert or update user data to the database
    $fbUserData['oauth_provider'] = 'facebook';
    $userData $user->checkUser($fbUserData);
    
    // Storing user data in the session
    $_SESSION['userData'] = $userData;
    
    // Get logout url
    $logoutURL $helper->getLogoutUrl($accessTokenFB_REDIRECT_URL.'logout.php');
    
    // Render Facebook profile data
    if(!empty($userData)){
        $output  '<h2>Facebook Profile Details</h2>';
        $output .= '<div class="ac-data">';
        $output .= '<img src="'.$userData['picture'].'"/>';
        $output .= '<p><b>Facebook ID:</b> '.$userData['oauth_uid'].'</p>';
        $output .= '<p><b>Name:</b> '.$userData['first_name'].' '.$userData['last_name'].'</p>';
        $output .= '<p><b>Email:</b> '.$userData['email'].'</p>';
        $output .= '<p><b>Gender:</b> '.$userData['gender'].'</p>';
        $output .= '<p><b>Logged in with:</b> Facebook</p>';
        $output .= '<p><b>Profile Link:</b> <a href="'.$userData['link'].'" target="_blank">Click to visit Facebook page</a></p>';
        $output .= '<p><b>Logout from <a href="'.$logoutURL.'">Facebook</a></p>';
        $output .= '</div>';
    }else{
        $output '<h3 style="color:red">Some problem occurred, please try again.</h3>';
    }
}else{
    // Get login url
    $permissions = ['email']; // Optional permissions
    $loginURL $helper->getLoginUrl(FB_REDIRECT_URL$permissions);
    
    // Render Facebook login button
    $output '<a href="'.htmlspecialchars($loginURL).'"><img src="images/fb-login-btn.png"></a>';
}
?>

<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Login with Facebook using PHP by CodexWorld</title>
<meta charset="utf-8">
</head>
<body>
<div class="container">
    <div class="fb-box">
        <!-- Display login button / Facebook profile information -->
        <?php echo $output?>
    </div>
</div>
</body>
</html>

Logout (logout.php)

If the user wishes to log out from their Facebook account, the logout.php file is loaded.

  • Remove access token and user data from the SESSION.
  • Redirect the user to the homepage.
<?php
// Include configuration file
require_once 'config.php';

// Remove access token from session
unset($_SESSION['facebook_access_token']);

// Remove user data from session
unset($_SESSION['userData']);

// Redirect to the homepage
header("Location:index.php");
?>

No comments:

Post a Comment

How to register multiple implementations of the same interface in Asp.Net Core?

 Problem: I have services that are derived from the same interface. public interface IService { } public class ServiceA : IService { ...