Google OAuth API provides an easy and powerful way to integrate the login system on the website. Google Login API allows the user to sign in to the website using their Google account without signing up on that website. The Google login system definitely helps to increase the number of subscribers on your website. Nowadays, almost all users have a Google account, and they can log in with their Google account without registering on your website.
Google login is one of the easiest ways to let users sign in to a PHP website without creating and remembering another username and password. With Google Identity Services (GIS), your website can display Google’s official Sign in with Google button, receive a Google ID token, verify that token on the server, and create a local login session.
Web developers can easily implement the login and registration system in a web application using Google OAuth 2.0 and PHP. In this tutorial, we will build a complete Login with Google using PHP and MySQL system using the current Google Identity Services JavaScript library.
The implementation uses:
Google recommends using the ID token’s sub claim as the stable unique identifier for a Google account rather than using the email address as the account identifier.
Before we start, let’s take a look at the file structure of the project:
login_with_google_account_using_php/ ├── config.php ├── index.php ├── login.php ├── logout.php ├── vendor/ │ └── ... └── style.css
The responsibilities of each file are as follows:
config.php: Contains the Google Client ID and database configuration.index.php: Displays the Google Sign-In button and handles the user interface for login and logout.login.php: Handles the server-side verification of the Google ID token and manages the user session using PHP.logout.php: Handles the user logout process and destroys the session.vendor/: Contains the Composer dependencies, including the Google API PHP Client library.style.css: Contains the CSS styles for the login page.The authentication flow in this example is:
The important part is that the browser does not decide whether the Google credential is valid. The credential is sent to login.php, where it is verified on the server using Google’s PHP client.
Google Identity Services returns a JWT ID token after the user signs in, and Google’s documentation recommends verifying that ID token on the server before using the account information for authentication.
Google Identity Services requires an OAuth 2.0 client ID. Google also uses the client ID when verifying the ID token on your backend.
To create a Google Cloud project and obtain a Web Client ID. Follow these steps:
https://www.example.com.123456789012-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com
config.php.To install the Google API PHP Client, you can use Composer. Run the following command in your project’s root directory:
composer require google/apiclient
Composer installs the Google API PHP Client and creates the vendor/ directory containing the Composer autoloader.
Note that if you don’t have Composer, you can download our source code and use it directly without installing the Google API PHP Client library. All the dependencies are already included in the vendor directory.
You need a MySQL database to store user information. Create a database and a users table that will hold the user information retrieved from Google account. You can use the following SQL commands to create the users table:
CREATE TABLE users (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
google_sub VARCHAR(255) NOT NULL,
email VARCHAR(320) NOT NULL,
email_verified TINYINT(1) NOT NULL DEFAULT 0,
name VARCHAR(255) NULL,
given_name VARCHAR(255) NULL,
family_name VARCHAR(255) NULL,
picture_url TEXT NULL,
gender VARCHAR(50) NULL,
locale VARCHAR(20) NULL,
hosted_domain VARCHAR(255) NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_users_google_sub (google_sub),
KEY idx_users_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
The config.php file contains the Google Client ID and database configuration.
GOOGLE_CLIENT_ID) to the value you obtained from the Google Cloud Console.DB_HOST, DB_NAME, DB_USER, DB_PASSWORD) according to your MySQL setup.There are also a helper function database() that establishes a connection to the MySQL database using the MySQLi extension. The function returns a mysqli object that can be used for executing queries.
<?php
// Enable strict mode for type checking
declare(strict_types=1);
// Google Client ID for OAuth 2.0 authentication
const GOOGLE_CLIENT_ID = 'YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com';
// Database configuration
const DB_HOST = 'localhost';
const DB_NAME = 'google_login_db';
const DB_USER = 'root';
const DB_PASSWORD = '';
// Start the session to manage user authentication state
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Helper function for database connection
function database(): mysqli
{
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$database = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$database->set_charset('utf8mb4');
return $database;
}
// Helper function to convert special characters to HTML entities for safe output
function e(mixed $value): string
{
return htmlspecialchars((string) ($value ?? ''), ENT_QUOTES, 'UTF-8');
}
?>
Create an index.php file that will handle the user-facing part of the authentication process. This page displays the Sign in with Google button and handles the Google Sign-In process. The page also checks if the user is already logged in by checking the session variable $_SESSION['google_user']. If the user is logged in, it displays their profile information; otherwise, it shows the Google Sign-In button.
Authenticated Google user’s information: Check if the user is logged in by verifying if the session variable $_SESSION['google_user'] is set to determine if the user is already logged in.
<?php
// Enable strict mode for type checking
declare(strict_types=1);
// Include the configuration file
require __DIR__ . '/config.php';
// Retrieve the user information from the session
$user = $_SESSION['google_user'] ?? null;
?>
Display Google Login Button: If the $user variable is null, it means the user is not logged in. In this case, the page displays the Google Sign-In button using the Google Identity Services JavaScript library. Otherwise, it shows the user’s profile information (Profile picture, Name, Email, Email verification status, Given name, Family name, Gender, Locale, Hosted domain, Google subject ID, etc.) and a logout button.
<?php if ($user === null): ?>
<!-- Display the Google Sign-In button if the user is not logged in -->
<section class="panel login-panel" aria-labelledby="login-title">
<div class="panel-mark">G</div>
<h2 id="login-title">Sign in to continue</h2>
<p class="muted">Your verified Google profile will be saved to the local database.</p>
<div id="google-button" class="google-button"></div>
<p id="status" class="status" role="status"></p>
</section>
<?php else: ?>
<!-- Display the user's profile information if logged in -->
<section class="panel profile-panel" aria-labelledby="profile-title">
<div class="profile-header">
<?php if (!empty($user['picture'])): ?>
<img class="avatar" src="<?= e($user['picture']) ?>" alt="Profile picture">
<?php else: ?>
<div class="avatar avatar-fallback"><?= e(strtoupper(substr($user['name'] ?: $user['email'], 0, 1))) ?></div>
<?php endif; ?>
<div>
<p class="eyebrow">Signed in successfully</p>
<h2 id="profile-title"><?= e($user['name'] ?: $user['email']) ?></h2>
</div>
</div>
<dl class="profile-grid">
<div><dt>Email</dt><dd><?= e($user['email']) ?></dd></div>
<div><dt>Email verified</dt><dd><?= $user['email_verified'] ? 'Yes' : 'No' ?></dd></div>
<div><dt>Given name</dt><dd><?= e($user['given_name'] ?: 'Not provided') ?></dd></div>
<div><dt>Family name</dt><dd><?= e($user['family_name'] ?: 'Not provided') ?></dd></div>
<div><dt>Gender</dt><dd><?= e($user['gender'] ?: 'Not provided by Google') ?></dd></div>
<div><dt>Locale</dt><dd><?= e($user['locale'] ?: 'Not provided') ?></dd></div>
<div><dt>Hosted domain</dt><dd><?= e($user['hd'] ?: 'Personal account') ?></dd></div>
<div><dt>Google subject ID</dt><dd class="breakable"><?= e($user['sub']) ?></dd></div>
</dl>
<a class="sign-out" href="logout.php">Sign out</a>
</section>
<?php endif; ?>
JavaScript for Google Sign-In: The JavaScript code initializes the Google Identity Services library, renders the Google Sign-In button, and handles the credential response. When the user successfully signs in with Google, the ID token is sent to the login.php backend for verification and session creation.
<?php if ($user === null): ?>
<!-- Load the Google Identity Services library -->
<script src="https://accounts.google.com/gsi/client" async defer></script>
<!-- JavaScript to handle the Google Sign-In button and credential response -->
<script>
function handleCredentialResponse(response) {
const status = document.getElementById('status');
status.textContent = 'Checking your Google account...';
const formData = new FormData();
formData.append('credential', response.credential);
fetch('login.php', { method: 'POST', body: formData, credentials: 'same-origin' })
.then((result) => result.json())
.then((result) => {
if (!result.success) {
throw new Error(result.message || 'Sign-in failed.');
}
window.location.reload();
})
.catch((error) => {
status.textContent = error.message;
});
}
window.addEventListener('load', () => {
google.accounts.id.initialize({
client_id: <?= json_encode(GOOGLE_CLIENT_ID, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>,
callback: handleCredentialResponse,
use_fedcm_for_button: true
});
google.accounts.id.renderButton(document.getElementById('google-button'), {
theme: 'outline',
size: 'large',
text: 'continue_with',
shape: 'rectangular',
width: 320
});
});
</script>
<?php endif; ?>
Create a login.php file that will handle the server-side verification of the Google ID token and manages the user session using PHP. It performs the following tasks:
<?php
// Enable strict mode for type checking
declare(strict_types=1);
// Loads Composer and application configuration
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/config.php';
// Set the response content type to JSON
header('Content-Type: application/json; charset=utf-8');
// Check if the request method is POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['success' => false, 'message' => 'POST requests only.']);
exit;
}
// Retrieve the Google credential from the POST data
$credential = $_POST['credential'] ?? '';
if (!is_string($credential) || $credential === '') {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Google credential is missing.']);
exit;
}
try {
// Verify the Google ID token using the Google Client library
$googleClient = new Google\Client(['client_id' => GOOGLE_CLIENT_ID]);
$payload = $googleClient->verifyIdToken($credential);
if ($payload === false || empty($payload['sub']) || empty($payload['email'])) {
throw new RuntimeException('The Google ID token could not be verified.');
}
// Store or update the user information in the database
$database = database();
$statement = $database->prepare(
'INSERT INTO users
(google_sub, email, email_verified, name, given_name, family_name, picture_url, gender, locale, hosted_domain)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
email = VALUES(email),
email_verified = VALUES(email_verified),
name = VALUES(name),
given_name = VALUES(given_name),
family_name = VALUES(family_name),
picture_url = VALUES(picture_url),
gender = VALUES(gender),
locale = VALUES(locale),
hosted_domain = VALUES(hosted_domain)'
);
$googleSub = (string) $payload['sub'];
$email = (string) $payload['email'];
$emailVerified = !empty($payload['email_verified']) ? 1 : 0;
$name = $payload['name'] ?? null;
$givenName = $payload['given_name'] ?? null;
$familyName = $payload['family_name'] ?? null;
$pictureUrl = $payload['picture'] ?? null;
$gender = $payload['gender'] ?? null;
$locale = $payload['locale'] ?? null;
$hostedDomain = $payload['hd'] ?? null;
$statement->bind_param(
'ssisssssss',
$googleSub,
$email,
$emailVerified,
$name,
$givenName,
$familyName,
$pictureUrl,
$gender,
$locale,
$hostedDomain
);
$statement->execute();
// Store the user information in the session for later use
$_SESSION['google_user'] = [
'sub' => $googleSub,
'email' => $email,
'email_verified' => $emailVerified,
'name' => $name,
'given_name' => $givenName,
'family_name' => $familyName,
'picture' => $pictureUrl,
'gender' => $gender,
'locale' => $locale,
'hd' => $hostedDomain,
];
echo json_encode(['success' => true]);
} catch (Throwable $exception) {
error_log($exception->getMessage());
http_response_code(500);
echo json_encode(['success' => false, 'message' => 'Sign-in could not be completed.']);
}
?>
Create a logout.php file that will handle the user logout process. It destroys the session and redirects the user back to the login page (index.php). The logout process is straightforward and ensures that the user’s session is properly terminated, preventing unauthorized access to protected resources using PHP SESSION.
<?php
// Enable strict mode for type checking
declare(strict_types=1);
// Start the session and clear all session data to log the user out
session_start();
$_SESSION = [];
// If the session uses cookies, delete the session cookie by setting its expiration time in the past
if (ini_get('session.use_cookies')) {
$parameters = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $parameters['path'], $parameters['domain'], $parameters['secure'], $parameters['httponly']);
}
// Destroy the session to log the user out
session_destroy();
header('Location: index.php');
exit;
?>
In this tutorial, we created a complete Login with Google using PHP and MySQL implementation using Google Identity Services. The system allows users to log in to your website using their Google account without the need for creating a new username and password. We have covered the entire process, including setting up the Google Cloud project, creating the MySQL database, implementing the frontend and backend logic, and managing user sessions.
The most important part of the implementation is the server-side verification of the Google ID token. Once the token is verified, the application can safely use the returned Google account information to create or update the local user account.
If you want to implement a more traditional registration and login system with PHP and MySQL, you can refer to the following tutorial for a secure implementation:
Looking for expert assistance to implement or extend this script’s functionality? Submit a Service Request
💰 Budget-friendly • 🌍 Global clients • 🚀 Production-ready solutions
Thank you very much for your post. I wanted to build a website with google login system, but did not know where to start. This post helped me so much to understand the process. Unfortunately, I am kind of stuck at the point of redirecting after log in. After clicking “allow”, it directs me back to the index.php page, which I guess, bounces me back to as I am not “logged in” from the account page. Do you have any idea what causes this issue? Thank you very much again!
That was a great tutorial for me. I have a suggestion about this tutorial, Can apply this tutorial with CodeIgniter or Laravel PHP frameworks?
We’ve already published Login with Google Account in CodeIgniter. Check this tutorial from here – http://www.codexworld.com/login-with-google-account-in-codeigniter/
thanks broo, this tut work perfectly..
Thank you very much..This is appreciated.
Thank You so much for the code
CodexWorld thanks
god bless u
Thank You so much for the code, its works fine for me.
Great script; straightforward implementation. Thanks.
I want to prevent Google from prompting to “Have offline access” when granting permission after the frist login.
In src/Google_Client.php, I see settings for “access_type” and “approval_prompt”. How can I change these to “offline” and “auto”, respectfully?
You are amazing….man!!!
So much useful .
I have a problem about Error: redirect_uri_mismatch, What should I do to solve this problem
@Adhy URL defined in
$redirectUrlvariable must be matched with the Redirect URI of Google Developers Console Project.Hi, nicee example
Question
How I can join facebook with google in one start ?
I would like to make the user only need to authenticate only once ? For now , every time I log in asking the user’s permission .
I’m having trouble getting the data from the google account into a mysql table. Where exactly is __construct() called?
@Ben Open the
includes/functions.phpfile, you’ll see the__construct()function. In this function you should need to change the $dbServer, $dbUsername, $dbPassword, and $dbName variables value with your database credentials.i am unable to find download links can u please email me sir?
Download the source code from here – http://demos.codexworld.com/download.php?url=https://app.box.com/s/op9uun1b6iiitxp8wj87wskgykonkhle
Great,I was searchig many link about the facebook and gmail login in website…I have tried many mores but here i have got everthing ..Great, Thanks Codexworld,
Thanks for your tutorial it really helped me..!
How can i redirect users to their own page instead of just account.php?
@Daniel Open the index.php file and go to the line no.21. Change the redirect URL with user profile link.
source file is not download how to i get the full source file pls forward to me any body share pls this mail id anu@stridec.com
@Anu You can download the source code from the above Download link. Also, we have sent the source code to your email id. Please check your email and let us know if you need further help.
Hi
Thank You This Tutorial Improve the Knowledge and solve Many Problem My Project isssued
You’re a lifesaver man. I’ve been struggling looking for up to date references for google login integration with my website, and this references suits my needs. THANKS!
Hello,
Can I do same thing with codeigniter framwork. please help me to find the solution.
@Yamini We’ve received many requests for this tutorial and we’ll publish this tutorial soon. Please subscribe our newsletter for getting the notification.
Thanks
i want also mobile number !!!!
Hi
I want the user to login with either facebook or google. When i tried combining your both codes i messed up somewhere. Can you please provide a tutorial on a combined version of social logins
TIA
Amit Anand
It’s very nice..
Thank you very much..
nice your every post helps me a lot ,thank you so much
It worked like Charm !!!!
Thank you very much 🙂
@John
These three errors occurred only for undefined
$redirect_urlvariable. Open theconfig.phpfile and make sure$redirect_urlvariable is defined.source file is not download how to i get the full source file pls forward to me any body share phs this mail id sakthidesign5677@gmail.com
@Sakthi
The source code has sent to your email. Please check.
i have some problem to use api . i can’t understand how to give “In the Authorized JavaScript origins field, enter your app origin. If you want to allow your app to run on different protocols, domains, or subdomains, then you can enter multiple origins.
In the Authorized redirect URI field, enter the redirect URL.” this information i am using localhost xamp server
@Rohit
If you use localhost server then Authorized JavaScript origins would be
http://localhostand Authorized redirect URIs would behttp://localhost/login-with-google-using-php. Also you can add multiple Authorized JavaScript origins and Authorized redirect URIs.Thank you very much… for your great tutorial…
It helped me a lot..
can u send same code for codeigniter
Awsme script
Thank you very much
Can you provide me same script for codegniter?
Wooo!!! Thank yoooooooooooooouuuuuu……!!!!!!!!!!!!
Im thankful for the blog article.Thanks Again. Keep writing.
I simply want to mention I am just very new to blogs and actually enjoyed this page. Very likely I’m likely to bookmark your site . You amazingly come with fabulous posts. Thanks a lot for revealing your web page.
great!thanks a lot
Interesting info you post on your blog, i have shared this article on my facebook
Wonderful article! That is the kind of info that should be shared across the web. Thank you =)
You share interesting posts here.
wow its amazing…nice post. thanks