OAuth 2.0 and JWT Authorization in PHP: A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why OAuth 2.0 and JWT in PHP

Modern web applications rarely work in isolation. Users expect single sign-on via Google, Facebook, or GitHub, and developers expect secure data exchange between microservices. Two key protocols — OAuth 2.0 (access delegation) and JWT (compact token format) — have become the de facto standard. In this article, we will break down how to implement OAuth 2.0 and JWT authorization in PHP from scratch, using only built-in language features and popular libraries. You will get ready-made code examples for integration with external providers and creating your own authentication system.



1. OAuth 2.0 Basics: Flows and Roles

OAuth 2.0 is an authorization protocol that allows third-party applications to obtain limited access to user resources without transmitting a password. It involves four roles:

  • Resource Owner — the user who owns the data.
  • Client — your PHP application requesting access.
  • Authorization Server — the server that issues tokens (e.g., Google).
  • Resource Server — the API that provides data based on the token.

The most popular flow for web applications is the Authorization Code Grant. It is secure because the token is transmitted through the server side, not through the browser. Let's look at the implementation in PHP.



1.1. Application Registration and Obtaining Client ID/Secret

Before writing code, register your application with a provider (e.g., in Google Cloud Console). You will receive client_id and client_secret, and also configure a redirect URI (e.g., https://yoursite.com/callback.php).



1.2. Implementing the Authorization Code Flow in PHP

Let's create two files: login.php (redirect to the authorization server) and callback.php (handle the response).



File login.php

<?phpsession_start();

$client_id = 'YOUR_CLIENT_ID';$redirect_uri = 'https://yoursite.com/callback.php';$state = bin2hex(random_bytes(16)); // CSRF protection$_SESSION['oauth_state'] = $state;

$params = http_build_query([ 'client_id' => $client_id, 'redirect_uri' => $redirect_uri, 'response_type' => 'code', 'scope' => 'openid email profile', 'state' => $state,]);

header('Location: https://accounts.google.com/o/oauth2/v2/auth?' . $params);exit;?>


File callback.php

<?phpsession_start();

// Check state (CSRF)if ($_GET['state'] !== $_SESSION['oauth_state']) { die('Error: invalid state');}

$client_id = 'YOUR_CLIENT_ID';$client_secret = 'YOUR_CLIENT_SECRET';$redirect_uri = 'https://yoursite.com/callback.php';

// Exchange code for token$ch = curl_init('https://oauth2.googleapis.com/token');curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'code' => $_GET['code'], 'client_id' => $client_id, 'client_secret' => $client_secret, 'redirect_uri' => $redirect_uri, 'grant_type' => 'authorization_code',]));curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$response = curl_exec($ch);curl_close($ch);

$data = json_decode($response, true);$access_token = $data['access_token'] ?? null;

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

echo 'Hello, ' . htmlspecialchars($userInfo['email']);?>

Important: Always check the state parameter. It protects against request forgery (CSRF).



2. JW

Blogs

Book Recommendations