Google Two Factor Authentication Login with PHP
Wall Script
Wall Script
Tuesday, June 14, 2016

Google Two Factor Authentication Login with PHP

In our previous post, explains you the login system using PHP with PDO connection. Here is an extra feature that can be added to login system for an extra layer of security. It is 2 factor authentication using Google Authenticator App for Android/iPhone. Your account could be at risk of having your password stolen. 2 step verification can protect from misuse of your account if someone have your password, because logging into your account always require a security code(this verification code is uniquely designed for your account, if you opt for verification code, an unique code is sent to your mobile for every 30-60 seconds) in the second step after you enter your password.

Google Two Factor Authentication with PHP


Download Script     Live Demo

With 2 step verification, we can protect our account with both password and mobile. Add this 2 factor authentication to make your account more stronger.

Get Google Authenticator on your phone
Download and install Google Authenticator application on your mobile device, use the following icons. You need this for 2 step user authentication, please watch the following demo video.

        

Demo Video



Users Table
User table contains all the users registration details, here you have to store user details with unique Google authentication code.
CREATE TABLE `users` (
`uid` int NOT NULL PRIMARY KEY AUTO_INCREMENT ,
`username` varchar(25) NOT NULL UNIQUE,
`password` varchar(200) NOT NULL ,
`email` varchar(100) NOT NULL,
`name` varchar(100) NOT NULL,
`profile_pic` varchar(200) NOT NULL,
`google_auth_code` varchar(16) NOT NULL /* 16 digit code */
);

Enable PDO extension for PHP, find this in php.ini configuration file.

The tutorial contains two folders called googleLib and class with PHP files.
googleLib
-- GoogleAuthenticator.php // Google Authentication Library
class
-- userClass.php
config.php // Database configration file
index.php // Login and Signup page
device_confimation.php // Device confirmation page.
home.php // User welcome page
logout.php // Logout Page
sessions.php // User session


config.php
Database connection configuration file, here you have to modify username, password and database details. If you are using other database modify PDO() driver connection value.
<?php
session_start();
/* DATABASE CONFIGURATION */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'username');
define('DB_PASSWORD', 'password');
define('DB_DATABASE', 'databasename');
define("BASE_URL", "http://localhost/PHPLoginHash/"); // Eg. http://yourwebsite.com

function getDB()
{
$dbhost=DB_SERVER;
$dbuser=DB_USERNAME;
$dbpass=DB_PASSWORD;
$dbname=DB_DATABASE;
try {
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->exec("set names utf8");
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}

}
?>

HTML Login Signup Form

This post will help you design HTML login and registration forms PHP Login System with PDO Connection.

userClass.php
This class contains there methods userLogin, userRegistion and userDetails.
<?php
class userClass
{
/* User Login */
public function userLogin($usernameEmail,$password)
{
try{
$db = getDB();
$hash_password= hash('sha256', $password); //Password encryption 
$stmt = $db->prepare("SELECT uid FROM users WHERE (username=:usernameEmail or email=:usernameEmail) AND password=:hash_password");
$stmt->bindParam("usernameEmail", $usernameEmail,PDO::PARAM_STR) ;
$stmt->bindParam("hash_password", $hash_password,PDO::PARAM_STR) ;
$stmt->execute();
$count=$stmt->rowCount();
$data=$stmt->fetch(PDO::FETCH_OBJ);
$db = null;
if($count)
{
$_SESSION['uid']=$data->uid; // Storing user session value
$_SESSION['google_auth_code']=$google_auth_code; //Stroing Google authentication code
return true;
}
else
{
return false;
}
}
catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}

}

/* User Registration */
public function userRegistration($username,$password,$email,$name,$secret)
{
try{
$db = getDB();
$st = $db->prepare("SELECT uid FROM users WHERE username=:username OR email=:email");
$st->bindParam("username", $username,PDO::PARAM_STR);
$st->bindParam("email", $email,PDO::PARAM_STR);
$st->execute();
$count=$st->rowCount();
if($count<1)
{
$stmt = $db->prepare("INSERT INTO users(username,password,email,name,google_auth_code) VALUES (:username,:hash_password,:email,:name,:google_auth_code)");
$stmt->bindParam("username", $username,PDO::PARAM_STR) ;
$hash_password= hash('sha256', $password); //Password encryption
$stmt->bindParam("hash_password", $hash_password,PDO::PARAM_STR) ;
$stmt->bindParam("email", $email,PDO::PARAM_STR) ;
$stmt->bindParam("name", $name,PDO::PARAM_STR) ;
$stmt->bindParam("google_auth_code", $secret,PDO::PARAM_STR) ;
$stmt->execute();
$uid=$db->lastInsertId(); // Last inserted row id
$db = null;
$_SESSION['uid']=$uid;
return true;
}
else
{
$db = null;
return false;
}

}
catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}

/* User Details */
public function userDetails($uid)
{
try{
$db = getDB();
$stmt = $db->prepare("SELECT email,username,name,google_auth_code FROM users WHERE uid=:uid");
$stmt->bindParam("uid", $uid,PDO::PARAM_INT);
$stmt->execute();
$data = $stmt->fetch(PDO::FETCH_OBJ); //User data
return $data;
}
catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
}
?>

index.php
Contains PHP and HTML code, works base on user form submit..
<?php
include("config.php");
if(!empty($_SESSION['uid']))
{
header("Location: device_confirmations.php");
}
include('class/userClass.php');
$userClass = new userClass();

require_once 'googleLib/GoogleAuthenticator.php';
$ga = new GoogleAuthenticator();
$secret = $ga->createSecret(); //This function will create unique 16 digit secret key

$errorMsgReg='';
$errorMsgLogin='';
/* Login Form */
if (!empty($_POST['loginSubmit']))
{
$usernameEmail=$_POST['usernameEmail'];
$password=$_POST['password'];
if(strlen(trim($usernameEmail))>1 && strlen(trim($password))>1 )
{
$uid=$userClass->userLogin($usernameEmail,$password);
if($uid)
{
$url=BASE_URL.'home.php';
header("Location: $url"); // Page redirecting to home.php 
}
else
{
$errorMsgLogin="Please check login details.";
}
}
}

/* Signup Form */
if (!empty($_POST['signupSubmit']))
{
$username=$_POST['usernameReg'];
$email=$_POST['emailReg'];
$password=$_POST['passwordReg'];
$name=$_POST['nameReg'];
/* Regular expression check */
$username_check = preg_match('~^[A-Za-z0-9_]{3,20}$~i', $username);
$email_check = preg_match('~^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$~i', $email);
$password_check = preg_match('~^[A-Za-z0-9!@#$%^&*()_]{6,20}$~i', $password);

if($username_check && $email_check && $password_check && strlen(trim($name))>0)
{
$uid=$userClass->userRegistration($username,$password,$email,$name);
if($uid)
{
$url=BASE_URL.'home.php';
header("Location: $url"); // Page redirecting to home.php 
}
else
{
$errorMsgReg="Username or Email already exists.";
}
}
}
?>
//HTML Code
....Login Form HTML Code....

....Signup Form HTML Code...

Note: You have to include JavaScript validations for better user experience.

device_confirmation.php
<?php
include('config.php');
if(empty($_SESSION['uid']))
{
header("Location: index.php");
}
include('class/userClass.php');
$userClass = new userClass();
$userDetails=$userClass->userDetails($_SESSION['uid']);
$secret=$userDetails->google_auth_code;
$email=$userDetails->email;

require_once 'googleLib/GoogleAuthenticator.php';
$ga = new GoogleAuthenticator();
$qrCodeUrl = $ga->getQRCodeGoogleUrl($email, $secret,'Your Application Name');
?>
//HTML Code
Enter the verification code generated by Google Authenticator app on your phone.
<div id="img">
<img src='<?php echo $qrCodeUrl; ?>' />
</div>

<form method="post" action="home.php">
<label>Enter Google Authenticator Code</label>
<input type="text" name="code" />
<input type="submit" class="button"/>
</form>

home.php
User welcome page, display user details base on user session value.
<?php
include('config.php');
include('class/userClass.php');
$userClass = new userClass();
$userDetails=$userClass->userDetails($_SESSION['uid']);

if($_POST['code'])
{
$code=$_POST['code'];
$secret=$userDetails->google_auth_code;
require_once 'googleLib/GoogleAuthenticator.php';
$ga = new GoogleAuthenticator();
$checkResult = $ga->verifyCode($secret, $code, 2);    // 2 = 2*30sec clock tolerance

if ($checkResult)
{
$_SESSION['googleCode']=$code;
}
else
{
echo 'FAILED';
}
}

include('session.php');
$userDetails=$userClass->userDetails($session_uid);
?>
//HTML Code
<h1>Welcome <?php echo $userDetails->name; ?></h1>
<h2> Email <?php echo $userDetails->email; ?></h2>
<a href="<?php echo BASE_URL; ?>logout.php">Logout</a>


session.php
his will validate and store the user session value.
<?php
if(!empty($_SESSION['uid']) && !empty($_SESSION['googleCode']))
{
$session_uid=$_SESSION['uid'];
$session_googleCode=$_SESSION['googleCode'];
}
if(empty($session_uid) && empty($session_googleCode))
{
$url=BASE_URL.'index.php';
header("Location: $url");
}
?>


logout.php
This code will clear the user and Google aunthentication session values.
<?php
include('config.php');
$session_uid='';
$session_googleCode='';
$_SESSION['uid']='';
$_SESSION['googleCode']='';
if(empty($session_uid) && empty($_SESSION['uid']))
{
$url=BASE_URL.'index.php';
header("Location: $url");
}
?>

web notification

38 comments:


  1. Mostrando traducción para awesome gracias
    En su lugar, traducir del aweson gracias
    awesome
    Thank you

    ReplyDelete
  2. Well,I love Google so definitely will love this! ♥

    ReplyDelete
  3. Connection failed: SQLSTATE[28000] [1045] Access denied for user 'a1832414_bali'@'10.1.1.31' (using password: YES)

    PHP Error Message

    Fatal error: Call to a member function bindParam() on a non-object in /home/a1832414/public_html/class/userClass.php on line 39



    Free Web Hosting



    What is this shit???

    ReplyDelete
  4. Man , Download Script , NOT FOUND :(

    ReplyDelete
  5. thanks for great tuturial.I have a question; how we can use this login and signup form with this method for wordpress site?

    ReplyDelete
    Replies
    1. There is a Google Authenticator plugin for Wordpress.

      Delete
  6. How to using password of google account to login?

    ReplyDelete
  7. working fine for Signup page But not on login page for me any help please?

    ReplyDelete
  8. Anyone can authenticate using his phone ? Is it related to user email id ?

    ReplyDelete
  9. I have done signup in demo. And try scan with same device which i used while signup then login was successful.
    But I used another device to scan QR code then also login successful.

    So, how it is secure? If hacker steal my password and try his/her device to scan QR code, then hacker can be able to login.
    Please guide me ASAP.

    ReplyDelete
    Replies
    1. A late response, but i just found the script. I agree on this. The QR code should only be visable on registration so it will be added to your account. On that point your mobile device can generate the 2FA code and you dont need the QR code anymore.

      So it should only be available on registration not at the login page

      Delete
  10. when i scan bar code i get the code and when i entered that code after that nothing happens.

    ReplyDelete
  11. demo is working fine..
    i downloaded the code and when i scan the bar code i get the security key after entering that security key nothing happens ....?

    ReplyDelete
  12. There is an error in the sql code. last comma after NULL should be removed (comma cant be at the end of an )

    `google_auth_code` varchar(16) DEFAULT NULL,

    i dont see the security in this though. scanning the bar code on creating my account is ok, but why do you display the barcode again after registration and i have a valid account. You should only show the 2FA field where i put in the code generated by my app on my phone

    ReplyDelete
  13. Hi Srini,

    It's a good tutorials. I have one question. Can we have a list of 8 digit recovery codes as google gives?

    ReplyDelete
    Replies
    1. I believe the recovery codes will not be generated by the app or API, however you have to generate it and store in DB against the user email. Later you have to verify with codes stored in the database

      Delete
  14. Many thanks in sharing and explaining, works awesome, appreciate...

    ReplyDelete
  15. Hello SRINIVAS TAMADA,

    I try your code on my website and it is working fine but did you see one mistake in your code.

    When you login and enter google code then you go on home.php page right. Now you try this: Do not logout your home.php and open again index.php on different tab here its goes directly device_confirmations.php page it is good. When you enter any random text or number in textbox or without enter anything in the textbox its directly go to home.php that's not good.
    If you have any solution for this please share me

    Thanks

    ReplyDelete
    Replies
    1. index.php should not be openable after login session generated, this is just opposite logic we use to not let people open after login page.

      Delete
  16. It is directly go on home.php page when you do not logout your account and open index.php on second tab

    ReplyDelete
  17. it's not working for me.. Code and calculatedCode didn't matched in verifyCode function..Any help?

    ReplyDelete
  18. Should we use GoogleAutheticator.php from that source :
    https://github.com/PHPGangsta/GoogleAuthenticator/blob/master/PHPGangsta/GoogleAuthenticator.php

    Because index.php reports :
    Fatal error: Uncaught Error: Class 'GoogleAuthenticator' not found in /index.php:11 Stack trace: #0 {main} thrown in /index.php on line 11

    ReplyDelete
  19. Authentication on localhost is successful but on the website the authentication error code

    ReplyDelete
  20. Dear Admin Please remove comma(,) in lat line of user.sql when download.

    ReplyDelete
  21. How to recover this hash password?

    ReplyDelete
  22. 100% work perfectly.
    just create database set username,password in config.php also set BASE_URL in config.php and test.

    working like magic.
    Thanks man you made my day.

    ReplyDelete
  23. Thanks. It's working well in mylocalhost, but on servers it doesn't. I think have to do something for time setup. can you assist me?

    ReplyDelete
  24. code is not matching in localhost

    ReplyDelete
  25. The 'users.sql has error(s) when importing into database using phpmysql.

    ReplyDelete
  26. in the demo url whenever i login QRcode is visible and any one can scan and login if they know my username and password

    ReplyDelete
  27. Thank you very much....this really helps me.

    ReplyDelete
  28. This comment has been removed by a blog administrator.

    ReplyDelete

  29. hello i am getting these errors
    Warning: include(class/userClass.php): failed to open stream: No such file or directory in /home/vhosts/onlinestockmanagement.xp3.biz/index.php on line 7

    Warning: include(): Failed opening 'class/userClass.php' for inclusion (include_path='.:/opt/remi/php72/root/usr/share/pear:/opt/remi/php72/root/usr/share/php:/usr/share/pear:/usr/share/php') in /home/vhosts/onlinestockmanagement.xp3.biz/index.php on line 7

    Fatal error: Uncaught Error: Class 'userClass' not found in /home/vhosts/onlinestockmanagement.xp3.biz/index.php:8 Stack trace: #0 {main} thrown in /home/vhosts/onlinestockmanagement.xp3.biz/index.php on line 8

    ReplyDelete

mailxengine Youtueb channel
Make in India
X