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.
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.
lvh.me
which is same as localhost.http://lvh.me/login.php
. We would be creating login.php
script shortly. Feel free to change the url as per your domain.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 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.
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]);
To download the entire code please visit this gist.