How to Implement Google Two Factor Authentication Login in PHP

Back in 2011, Google released two factor authentication for G-mail to generate one time login tokens. This Google two factor authentication is the type of authentication that provides unambiguous identification of users with the combination of two different components.

This type of authentication provides an additional layer of security as attacker is unlikely to able to crack both layers to get access. In fact, most websites have now implemented Google two factor authentication login including Facebook, eBay, Yahoo, Paypal, and many others.

Google Two Factor Authentication in PHP

The easiest way to implement Google two factor authentication in your PHP website is by using the Google authenticator. The Google authenticator provides Google two factor authentication api for Google account logins and for other websites. Moreover, the Google authenticator app is also available in the Android, iPhone, and Blackberry app store that is based on following two proposed standards:

  • Time-Based One Time Password
  • HMAC-Based One Time Password

And, for PHP part, Google2FA PHP package will be used.

Now, in this PHP tutorial, we’ll see step-by-step process for implementing Google two factor authentication API in a PHP website.

Also Read: How to Integrate Captcha Validation in Your PHP Website

Let’s Get Started

First, login into your phpmyadmin. General login URL for local is – http://localhost/phpmyadmin

Click on database, enter database name, and press create button.

Now, select the database you created, and find import button. Click on browse button, download authentication_demo.sql and select it as database.

Here, we’ve successfully created database, now put JS and CSS file into project directory.

Use – Include (‘class/userclass.php’); to save information in database.

And, require_once ‘googleLib/GoogleAuthenticator.php’; to generate barcode with googlelib.

To decode this barcode, you’ll need Google authenticator application (Android / iOS).

Below is the code for Index.php file.

Index.php

<?php
include("config.php");
if(!empty($_SESSION['iUserId'])) {
    header("Location: device_confirmations.php");
}

include('class/userClass.php');
$userClass = new userClass();

require_once 'googleLib/GoogleAuthenticator.php';
$authenticator = new GoogleAuthenticator();
$secret = $authenticator->createSecret();

$errorMsgReg = '';
$errorMsgLogin = '';

if (!empty($_POST['loginSubmit'])) {
    $emailId = $_POST['vEmailId'];
    $password = $_POST['vPassword'];
    if (strlen(trim($emailId)) > 1 && strlen(trim($password)) > 1) {
    $userId = $userClass->userLogin($emailId, $password, $secret);
    if ($userId) {
        header("Location: device_confirmations.php");
    } else {
        $errorMsgLogin = "Please check login details.";
    }
    }
}

if (!empty($_POST['signupSubmit'])) {
    $username = $_POST['vUsername'];
    $email = $_POST['vEmailId'];
    $password = $_POST['vPassword'];
    $name = $_POST['vFullName'];
    $usernameCheck = preg_match('~^[A-Za-z0-9_]{3,20}$~i', $username);
    $emailCheck = preg_match('~^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$~i', $email);
    $passwordCheck = preg_match('~^[A-Za-z0-9!@#$%^&*()_]{6,20}$~i', $password);

    if ($usernameCheck && $emailCheck && strlen(trim($name)) > 0) {
     $uid = $userClass->userRegistration($username, $password, $email, $name, $secret);
    if ($uid) {
        header("Location: device_confirmations.php");
    } else {
        $errorMsgReg = "Username or Email already exits.";
    }
    } else {
    $errorMsgReg = "Enter valid details.";
    }
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>2-Step Verification</title>
    <link rel="stylesheet" type="text/css" href="style.css" charset="utf-8" />
</head>
<body>
    <div id="container">
        <h1>2-Step Verification</h1>
        <div id="login">
            <h3>Login</h3>
            <form method="post" action="" name="login">
                <label>Username or Email</label>
                <input type="text" name="vEmailId" autocomplete="off" />
                <label>Password</label>
                <input type="password" name="vPassword" autocomplete="off"/>
                <div class="errorMsg"><?php echo $errorMsgLogin; ?></div>
                <input type="submit" class="button" name="loginSubmit" value="Login">
            </form>
        </div>
        <div id="signup">
            <h3>Registration</h3>
            <form method="post" action="" name="signup">
                <label>Name</label>
                <input type="text" name="vFullName" autocomplete="off" />
                <label>Email</label>
                <input type="text" name="vEmailId" autocomplete="off" />
                <label>Username</label>
                <input type="text" name="vUsername" autocomplete="off" />
                <label>Password</label>
                <input type="password" name="vPassword" autocomplete="off"/>
                <div class="errorMsg"><?php echo $errorMsgLogin; ?></div>
                <input type="submit" class="button" name="signupSubmit" value="Signup">
            </form>
        </div>
    </div>
</body>
</html>
Copy to Clipboard

Connection.php

<?php
session_start();

/* DATABASE CONFIGURATION */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', '{USER NAME}');
define('DB_PASSWORD', '{PASSWORD}');
define('DB_DATABASE', 'authentication_demo');
define("BASE_URL", "http://localhost/AuthenticationDemo/"); // 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();
    }
}
?>
Copy to Clipboard

Note: change value of HOST , USERNAME , PASSWORD , DATABASE_NAME after change run your connection.php file in browser.

device_confirmations.php

Once you see your barcode after login, scan the barcode with Google authenticator application, and save the generated number to insert into text box.

<?php
include 'config.php';

if (empty($_SESSION['iUserId'])) {
    header('Location: index.php');
}

include 'class/userClass.php';
$userClass = new userClass();
$userDetails = $userClass->userDetails($_SESSION['iUserId']);
$secret = $userDetails->vAuthCode;
$email = $userDetails->vEmailId;

require_once 'googleLib/GoogleAuthenticator.php';

$ga = new GoogleAuthenticator();

$qrCodeUrl = $ga->getQRCodeGoogleUrl($email, $secret, 'spaceo demo');
?> 

</DOCTYPE html>
<html>
<head>
    <title>2-Step Verification</title>
    <link rel="stylesheet" type="text/css" href="style.css" charset="utf-8" />
</head>
<body>
<div id="container">
    <h1>2-Step Verification</h1>
    <div id="device">
    <p>Enter the verification code generated by Authenticator on your phone.</p>
        <div id="img">
            <img src='<?php echo $qrCodeUrl; ?>' />
        </div>

        <form method="post" action="home.php">
            <label>Enter Authenticator Code</label>
            <input type="text" name="code" </label>
            <input type="submit" class="button"</label>
        </form>
    </div>
    <div style="text-align:center">
        <h3<Get Authenticator on your phone</h3>
        <a href="https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8" target="_blank">
            <img class='app' src="images/iphone.png" />
        </a>

        <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en" target="_blank">
            <img class="app" src="images/android.png" />
        </a>
    </div>
</div>
</body>
</html>
Copy to Clipboard

home.php

<?php
include('config.php');
include('class/userClass.php');

$userClass = new userClass();
$userDetails = $userClass->userDetails($_SESSION['iUserId']);

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

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

include('session.php');
$userDetails = $userClass->userDetails($session_uid);
?>
<!DOCTYPE html>
<html>
    <head>
    <title>2-Step Verification</title>
    <link rel="stylesheet" type="text/css" href="style.css" charset="utf-8" />
    </head>
    <body>
    <div id="container">
        <h1>Welcome <?php echo $userDetails->vFullName; ?></h1>
        <pre>
        <?php print_r($userDetails); ?>
        </pre>
        <h4><a href="<?php echo BASE_URL; ?>logout.php">Logout</a></h4>
        </div>
    </body>
</html>
Copy to Clipboard

That’s It!

Want to Develop a Web Application?

Need to validate your app idea or consult with an expert? Get a free consultation now!

Cta Image

Using these simple steps, you can easily add PHP two factor authentication login. And, it’s also possible to add an additional layer in this authentication process to provide higher security, but the implementation can get tricky. So, It’s better that you talk to experts or hire PHP developers, if you’d also like to implement it in your PHP website.

Apart from implementing Google two factor authentication for security you can further prevent spam by add a captcha validation in PHP forms on your website.

Also, if you are planning to build a PHP website from scratch then you could get in touch with us as we are a leading PHP development company with an experienced and skilled team. We can help you not only with the implementation of two-factor authentication, and building your website as well as with other security measures to protect your website from potential threats.

Bhaval Patel

Written by

Bhaval Patel is a Director (Operations) at Space-O Technologies. He has 20+ years of experience helping startups and enterprises with custom software solutions to drive maximum results. Under his leadership, Space-O has won the 8th GESIA annual award for being the best mobile app development company. So far, he has validated more than 300 app ideas and successfully delivered 100 custom solutions using the technologies, such as Swift, Kotlin, React Native, Flutter, PHP, RoR, IoT, AI, NFC, AR/VR, Blockchain, NFT, and more.