Google OAuth 2.0 Tutorial

Add Login with Google to Your PHP Website

No library, no Composer — just pure PHP and cURL. Step-by-step guide to implementing Google OAuth login, saving users to MySQL, and tracking activity.

20 min read Beginner–Intermediate PHP · MySQL · Bootstrap 5
Google Sign In Button

What You Will Build

By the end of this tutorial, your PHP website will have:

  • A "Continue with Google" login button
  • Automatic user registration on first login
  • Session-based login state in navbar
  • MySQL table storing Google user data
  • An admin page to view all registered emails
No Composer needed. This tutorial uses only built-in PHP cURL — works on any shared hosting like LankaHost, Hostinger, or cPanel servers.
Files We Will Create
📁 public_html/
  📁 auth/
    📄 google-config.php  ← NEW
    📄 google-callback.php  ← NEW
  📄 login.php  ← UPDATE
  📄 includes/head.php  ← UPDATE navbar
  📄 gmail-list.php  ← NEW (admin)
STEP 01

Create Google Cloud Project & OAuth Credentials

Go to console.cloud.google.com and use an existing project or create a new one.

Google Cloud Console
1.1 — Configure OAuth Consent Screen
  1. Go to APIs & Services → OAuth consent screen (or Google Auth Platform)
  2. Click Get started
  3. App name: YourSiteName
  4. User support email: your Gmail
  5. Audience: External
  6. Contact email: your Gmail
  7. Click Create
1.2 — Create OAuth Client ID
  1. Go to Clients → Create Client
  2. Application type: Web application
  3. Name: MyWebsite
  4. Authorized JavaScript origins:
    https://www.yourdomain.com
  5. Authorized redirect URIs:
    https://www.yourdomain.com/auth/google-callback.php
  6. Click Create
Save your credentials! Copy both Client ID and Client Secret to Notepad. You'll need them in the next step.
STEP 02

Create auth/google-config.php

In your cPanel File Manager, create a folder called auth inside public_html. Then create google-config.php inside it.

PHP
<?php
define('GOOGLE_CLIENT_ID',     'YOUR_CLIENT_ID.apps.googleusercontent.com');
define('GOOGLE_CLIENT_SECRET', 'YOUR_CLIENT_SECRET');
define('GOOGLE_REDIRECT_URI',  'https://www.yourdomain.com/auth/google-callback.php');
Replace the placeholder values with your real Client ID and Client Secret from Google Cloud Console. Never share or commit these to GitHub.
STEP 03

Create auth/google-callback.php

This is the most important file. It handles the entire OAuth flow — no external library needed, just PHP cURL.

PHP
<?php
session_start();
require_once 'google-config.php';

// Database connection
$conn = new mysqli("localhost", "db_user", "••••••••", "db_name");

// Step 1: Redirect to Google if no code
if (!isset($_GET['code'])) {
    $params = [
        'client_id'     => GOOGLE_CLIENT_ID,
        'redirect_uri'  => GOOGLE_REDIRECT_URI,
        'response_type' => 'code',
        'scope'         => 'email profile',
        'access_type'   => 'online',
    ];
    $url = 'https://accounts.google.com/o/oauth2/auth?'
           . http_build_query($params);
    header('Location: ' . $url);
    exit;
}

// Step 2: Exchange code for access token
$tokenData = [
    'code'          => $_GET['code'],
    'client_id'     => GOOGLE_CLIENT_ID,
    'client_secret' => GOOGLE_CLIENT_SECRET,
    'redirect_uri'  => GOOGLE_REDIRECT_URI,
    'grant_type'    => 'authorization_code',
];
$ch = curl_init('https://oauth2.googleapis.com/token');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($tokenData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tokenResponse = json_decode(curl_exec($ch), true);
curl_close($ch);

if (!isset($tokenResponse['access_token'])) {
    header('Location: /login.php?error=token_failed');
    exit;
}

// Step 3: Get user info from Google
$ch = curl_init('https://www.googleapis.com/oauth2/v2/userinfo');
curl_setopt($ch, CURLOPT_HTTPHEADER,
    ['Authorization: Bearer ' . $tokenResponse['access_token']]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$userInfo = json_decode(curl_exec($ch), true);
curl_close($ch);

$google_id = $userInfo['id'];
$email     = $userInfo['email'];
$name      = $userInfo['name'];
$avatar    = $userInfo['picture'];

// Step 4: Auto-create table & save user
$conn->query("CREATE TABLE IF NOT EXISTS gmails (
    id INT AUTO_INCREMENT PRIMARY KEY,
    google_id VARCHAR(100) UNIQUE,
    name VARCHAR(150),
    email VARCHAR(150) UNIQUE,
    avatar VARCHAR(500),
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)");

$stmt = $conn->prepare(
    "SELECT id, name FROM gmails WHERE google_id=? OR email=?");
$stmt->bind_param("ss", $google_id, $email);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    $user = $result->fetch_assoc();
} else {
    $stmt2 = $conn->prepare(
        "INSERT INTO gmails (google_id,name,email,avatar) VALUES (?,?,?,?)");
    $stmt2->bind_param("ssss",
        $google_id, $name, $email, $avatar);
    $stmt2->execute();
    $user = ['id' => $conn->insert_id, 'name' => $name];
}

// Step 5: Set session & redirect
$_SESSION['user_id']    = $user['id'];
$_SESSION['user_name']  = $user['name'] ?? $name;
$_SESSION['user_email'] = $email;
$_SESSION['avatar']     = $avatar;

header('Location: /index.php');
exit;
The CREATE TABLE IF NOT EXISTS line auto-creates the gmails table on first login — no need to run SQL manually.
STEP 04

Update login.php — Google Button Only

Replace your old username/password form with just a Google button.

PHP
<?php
session_start();
require_once 'auth/google-config.php';

$params = [
    'client_id'     => GOOGLE_CLIENT_ID,
    'redirect_uri'  => GOOGLE_REDIRECT_URI,
    'response_type' => 'code',
    'scope'         => 'email profile',
    'access_type'   => 'online',
];
$googleLoginUrl = 'https://accounts.google.com/o/oauth2/auth?'
                  . http_build_query($params);

require_once 'includes/head.php';
?>

<main class="container">
  <div class="card shadow-lg border-0 mx-auto"
       style="max-width:450px;margin-top:80px;margin-bottom:80px;">
    <div class="card-body p-5">
      <div class="text-center mb-4">
        <i class="bi bi-person-circle" style="font-size:3rem;color:#0d6efd;"></i>
        <h2 class="fw-bold mt-2">Sign In</h2>
        <p class="text-muted">Use your Google account to continue</p>
      </div>
      <div class="d-grid">
        <a href="<?= $googleLoginUrl ?>"
           class="btn btn-outline-dark btn-lg d-flex align-items-center
                  justify-content-center gap-3">
          <img src="https://developers.google.com/identity/images/g-logo.png"
               width="24" height="24">
          <span class="fw-bold">Continue with Google</span>
        </a>
      </div>
    </div>
  </div>
</main>
Preview — What the button looks like:
Google Continue with Google
STEP 05

Update Navbar to Show Logged-In User

In includes/head.php, make sure session_start() is at the very top. Then replace the Login button in your navbar with this:

PHP + HTML
<?php if (isset($_SESSION['user_id'])): ?>
  <!-- Logged in -->
  <div class="d-flex align-items-center gap-2">
    <img src="<?= htmlspecialchars($_SESSION['avatar']) ?>"
         width="36" height="36" class="rounded-circle border">
    <span class="fw-semibold">
      <?= htmlspecialchars($_SESSION['user_name']) ?>
    </span>
    <a href="/logout.php" class="btn btn-outline-danger btn-sm">Logout</a>
  </div>
<?php else: ?>
  <!-- Not logged in -->
  <a href="/login.php" class="btn btn-outline-dark">Login</a>
<?php endif; ?>
STEP 06

Admin Page — View All Google Users

Create gmail-list.php in your site root. Access it with a secret key in the URL for protection.

PHP
<?php
// Simple key protection
$admin_pass = "your_secret_key";
if (!isset($_GET['key']) || $_GET['key'] !== $admin_pass) {
    die("<h3 style='color:red'>Access Denied</h3>");
}

// Download emails as .txt
if (isset($_GET['download'])) {
    $result2 = $conn->query("SELECT email FROM gmails");
    $emails = [];
    while ($row = $result2->fetch_assoc())
        $emails[] = $row['email'];
    header('Content-Type: text/plain');
    header('Content-Disposition: attachment; filename="emails.txt"');
    echo implode(', ', $emails);
    exit;
}

Access the admin page at:

https://www.yourdomain.com/gmail-list.php?key=your_secret_key
Change your_secret_key to something unique and hard to guess. Never share this URL publicly.
STEP 07

Publish the OAuth App (Allow All Google Accounts)

By default your app is in Testing mode — only test users can log in. To allow anyone:

  1. Go to Google Cloud Console → Google Auth Platform → Audience
  2. Click "Publish App"
  3. Confirm the prompt
After publishing, any Google account can log in to your site — no more "test users only" restriction.
BONUS

Track User Activity (Page Views, Job Clicks)

Once users are logged in, you can track what they do on your site. First create a tracking table:

SQL
CREATE TABLE page_views (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT,
  email VARCHAR(150),
  page VARCHAR(300),
  visited_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

Then add this snippet to any page you want to track (e.g. jobs.php, courses.php):

PHP
if (isset($_SESSION['user_id'])) {
    $uid   = $_SESSION['user_id'];
    $email = $_SESSION['user_email'];
    $page  = $_SERVER['REQUEST_URI'];
    $conn->query(
        "INSERT INTO page_views (user_id,email,page)
         VALUES ('$uid','$email','$page')"
    );
}
What You Can Do With This Data
Data CollectedHow to Use It
Pages visitedKnow which content is most popular
Job clicksSee which job categories get most interest
Course viewsDecide which courses to build next
Email listSend newsletters and batch announcements
Login frequencyFind your most active users

Final Checklist

  • Google Cloud project created
  • OAuth consent screen configured (External)
  • OAuth Client ID and Secret saved
  • auth/google-config.php created
  • auth/google-callback.php created
  • login.php updated with Google button
  • Navbar shows avatar + name after login
  • gmails table auto-created on first login
  • gmail-list.php admin page working
  • App published (not in testing mode)
Tech Stack Used
PHP 8.x MySQL Bootstrap 5 OAuth 2.0 cURL Sessions