Login with Google Account using PHP

In this article we’ll learn how you can let your app users login with Google Account into your PHP web application using Google PHP Client version 2. It’s assumed that you have already installed composer and are using a version of PHP greater than 5.4. To view the entire code please visit this gist.

Create OAuth 2.0 Client ID and Secret Key

To get started we’ll need Client ID and Client Secret. For that we’ll have to create a Google API console project. Follow belows steps.

  • Go to Google API Console
  • Click on the Projects drop down in top left corner.
    Login with Google Account using PHP - Click on project tab
  • In the popup that shows up click on “New Project” in top right.
    Login with Google Account using PHP - Select new project
  • Click on “Create”.
    Login with Google Account using PHP - Create Project Modal
  • Click on “Credentials” in left sidebar.
    Login with Google Account using PHP - Click on Credentials
  • Click on “OAuth consent screen”.
    Login with Google Account using PHP - OAuth Screen
  • In “Application name” specify any name of your choice
  • “Support email” must have autofilled your current Gmail address. Feel free to change it to any different email address.
  • In “Authorized domains” specify the domain that you would be using. If you are testing this locally you can enter lvh.me which is same as localhost.
  • You can leave rest other fields empty.
  • Click on save
  • Then in “Credentials” tab click on “Create credentials” and then “OAuth client ID”.
  • Select “Web application”.
    Login with Google Account using PHP - Redirect urls
  • Enter any name in “Name”.
  • Whatever url is specified in “Authorized redirect URIs” post login Google would be redirecting the user to this url with some authentication data. So if you are trying this out locally you can specify http://lvh.me/login.php. We would be creating login.php script shortly. Feel free to change the url as per your domain.
  • Click on “Create”
  • Note down the Client ID and Client Secret in the modal that shows up. We’ll be needing this in our login script.

Google client library

Google has provided PHP library that has lots of functions to interact with Google APIs usign OAuth2. Let’s go ahead and install it. Assuming your project root is /var/www/html issue below commands.

cd /var/www/html
composer require google/apiclient:"^2.0"

Create login script

Create a login.php file. Include vendor/autoload.php so that we can include the Google library we installed using Composer.

Now let's define some constants for Google Client ID and Google Client Secret.

define('GOOGLE_CLIENT_ID', 'enter-google-client-id');
define('GOOGLE_CLIENT_SECRET', 'enter-google-client-secret');
define('GOOGLE_REDIRECT_URL', 'http://lvh.me/login.php');

GOOGLE_REDIRECT_URL is url to current login.php script. Feel free to change it as per your domain.

Now let's create a new instance of Google client.

$client = new Google_Client();
$client->setApplicationName('Sample Google Login by Perials');
$client->setClientId(GOOGLE_CLIENT_ID);
$client->setClientSecret(GOOGLE_CLIENT_SECRET);
$client->setRedirectUri(GOOGLE_REDIRECT_URL);

Post login Google would be redirecting user with code query string. We'll be needing this to generate OAuth2 token.

if (isset($_GET['code'])) {
    $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
    // store the token in Session
    $_SESSION['access_token'] = $token;
}

Whenever we have code in query string we fetch the token and set a Session. If Session is set then we'll assume user is logged in. If not then we'll show him a login url.

// if access_token session is set then user has already logged in
if($_SESSION['access_token']) {
    $attributes = $client->verifyIdToken($_SESSION['access_token']['id_token'], GOOGLE_CLIENT_ID);
    print_r($attributes);
    // Above will print an array which should contain below keys
    // name
    // picture
    // email
}
else {
    $scopes = [ Google_Service_Oauth2::USERINFO_PROFILE, Google_Service_Oauth2::USERINFO_EMAIL ];
    $authUrl = $client->createAuthUrl($scopes);
    ?>
    Click to login via Google
    

Please note that we haven't handled all error cases. Like say in current script if we receive any invalid value in code query string then that case needs to be handled.

Error - Cannot handle token prior to {date}

Usually the above code works well but there could be a chance that you may encounter a BeforeValidException if your application server's clock and auth server's clock are not in sync. The message displayed on the browser would be something like Cannot handle token prior to 2019-05-02T13:01:09-0800. This error appears when user logs in to his google account and is redirected back to your app.
This has been reported in stackoverflow and is supposedly fixed in this pull request. But if your server's time is way out of sync (say a different timezone) then you may still face the issue.
Below is the workaround for this issue. Unlike the solutions mentioned in above forums we won't be touching any file in the vendor (created by composer) directory.
In above code replace below line

$client = new Google_Client();

with below lines


// this is fix for leeway issue with JWT token
$jwt = new Firebase\JWT\JWT;
$jwt::$leeway = 5; // adjust this value

// we explicitly pass jwt object whose leeway is set to 5
$this->client = new Google_Client(['jwt' => $jwt]);

Download entire code for Login with Google Account

To download the entire code please visit this gist.

Leave a Reply

Your email address will not be published. Required fields are marked *