Earlier I showed you how easily you can integrate Facebook login system with your PHP website. Let’s hit the final nail in the coffin with another option for your users – Login with Google. Everybody has a Gmail account (no stats available) and they’re always logged in. So for someone like me who doesn’t use Facebook (Follow me on Twitter) Login with Google is the best choice to take.
A lot of tutorials out there over complicate things more than they need to which makes it harder for first timers to integrate the system or worse – integrate the system the wrong way! So I’ll try to keep things organized and simple. Let me know in the comments below if you get confused by any step.
The guide provided by Google for this purpose is pretty simple and easy to use but there are some pitfalls that developers fall into. I’ll try to explain them along the way. Like before, I assume you already have a website or are working on one which has a regular login and sign up system OR you know how to do it because I won’t get into “How to create a login system”. Future article maybe? Anyways let’s get started.
1. Add the Button
First things first, let’s add a button that user will click upon to trigger Sign-in with Google. Add this code wherever you want the button to appear.
<div class="g-signin2" data-onsuccess="googleSignIn" data-longtitle="true" data-width="320" data-theme="dark"></div>
Include the library
<script src="https://apis.google.com/js/platform.js?onload=googleLoad" async defer></script>
Specify your App’s client Id. Add this to the head section of the page
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
You’ll get your client Id from Google’s Developer Console. More details on how to do that here.
At this point, you should have the button appearing, albeit it won’t work. Let’s make that happen. When the page loads the first javascript function that’s going to execute is googleLoad()
.
2. Defining Javascript Functions
function googleLoad() { gapi.load('auth2', function() { gapi.auth2.init(); }); }
This function just initializes the library and loads the button and does not take any other action. Although, when the button loads it will execute the function googleSignIn()
as we specified in the button above so let’s define that as well.
function googleSignIn(googleUser) { console.log('google login executed'); var token = googleUser.getAuthResponse().id_token; var xhr = new XMLHttpRequest(); xhr.open('POST', 'includes/glogin/g-callback.php'); // specify your callback file location here xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onload = function() { var response = xhr.responseText; console.log(response); if(response == 0) googleSignout(); else location.reload(); }; xhr.send('idtoken=' + token); }
You can add these functions to a separate script file or between <script></script>
tags in an HTML/PHP page. That’s a handful but really it’s just an ajax request to www.domain.com/includes/glogin/g-callback.php where it POSTs a token received from Google. We’ll use this token to make another call to the sign in api to get user’s information.
The function also calls one more function googleSignout()
in case the response is invalid but we’ll define it later. Let’s move on to handling the token and getting user info.
3. PHP Callback File
To call the api you first need to include the PHP library provided by Google. Follow the instructions there to install the client in your project. Remember, if you’re not using Composer, download your package from the Release tab not the green button on the right. Here’s how the php file looks like
<?php require '../config.php'; require 'vendor/autoload.php'; if(isset($_POST['idtoken'])) $id_token = $_POST['idtoken']; else die(); $client = new Google_Client(['client_id' => 'YOUR-APP-CLIENT-ID.apps.googleusercontent.com']); $payload = $client->verifyIdToken($id_token); if ($payload) { $profileSet['token'] = $payload['sub']; $profileSet['name'] = $payload['name']; $profileSet['email'] = $payload['email']; $profileSet['source'] = 'google'; $profileSet['avatar'] = $payload['picture']; if(socialLogin($profileSet, 1, 'google')) echo 1; else echo 0; } else { $_SESSION['msg']['type'] = 'error'; $_SESSION['msg']['content'] = 'Failed to authenticate.'; echo 0; } ?>
So first I include my config file which has my database connection rules and global constants defined and stuff. The second line includes the Google Client Library for PHP (without composer). We check for the existence of idtoken
and if it’s not found, script terminates there.
Add your client id in the next lines, the same as you added in the head section earlier and execute $client->verifyIdToken($id_token)
. If everything checks out, you’ll have all the information google sends. Examine the $payload
array to see what information you need to keep and what to discard.
I’m using a custom function of mine socialLogin()
here to create a new account if the user is logging in for the first time or sign him in if he’s an existing user. I return 0 or 1 to the javascript based on if the action was successful. 0 means failure and execute google’s signout method. If 1 is returned I reload the page because then the $_SESSION
would have the user’s details. You can send the user to a different page for instance, the dashboard of your backend, if you wish.
4. Logout
If you read my previous article for Login with Facebook, you might have noticed I do not recommend signing out a user from your app when he signs out of your website. Well Google sign-in is different, if you sign out a user in the usual way of destroying his session and cookie data, and the user comes back to your site, the googleSignIn()
function will execute automatically and call the php file to log the user back in. The user might not like that. In fact, the user can never log out of your site if he doesn’t log out of Google and that would be infuriating. So when the user clicks “Log out” or the system logs out the user for whatever reason, you should explicitly log the user out of your app on Google. This won’t log him out of his Google account though.
For that I use this javascript:
function googleSignout(){ var auth2 = gapi.auth2.getAuthInstance(); auth2.signOut().then(function () { // console.log('signed out'); window.location = "https://www.domain.com/signout/"; }); } $('.logout').on('click', function(e){ e.preventDefault(); googleSignout(); });
I intercept the click on the log out button and execute the Google’s signout method instead. When that’s done I send the user to my signout link where his php session and cookies are destroyed.
Bonus
The signout function does not work on localhost so don’t bother with that. To test the system fully, upload your website to a live server. You could also try to map a domain to your localhost server.