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.
By the end of this tutorial, your PHP website will have:
Go to console.cloud.google.com and use an existing project or create a new one.
YourSiteNameMyWebsitehttps://www.yourdomain.com
https://www.yourdomain.com/auth/google-callback.php
auth/google-config.phpIn your cPanel File Manager, create a folder called auth inside public_html. Then create google-config.php inside it.
<?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');
auth/google-callback.phpThis is the most important file. It handles the entire OAuth flow — no external library needed, just PHP cURL.
<?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;
CREATE TABLE IF NOT EXISTS line auto-creates the gmails table on first login — no need to run SQL manually.login.php — Google Button OnlyReplace your old username/password form with just a Google button.
<?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>
In includes/head.php, make sure session_start() is at the very top. Then replace the Login button in your navbar with this:
<?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; ?>
Create gmail-list.php in your site root. Access it with a secret key in the URL for protection.
<?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
your_secret_key to something unique and hard to guess. Never share this URL publicly.By default your app is in Testing mode — only test users can log in. To allow anyone:
Once users are logged in, you can track what they do on your site. First create a tracking table:
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):
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')" ); }
| Data Collected | How to Use It |
|---|---|
| Pages visited | Know which content is most popular |
| Job clicks | See which job categories get most interest |
| Course views | Decide which courses to build next |
| Email list | Send newsletters and batch announcements |
| Login frequency | Find your most active users |