Implementing Single Sign-On (SSO) with PHP: A Step-by-Step Guide
This tutorial explains how to build a PHP-based single sign‑on system using a main login application, a shared authentication service backed by MySQL and Redis, and multiple external applications, providing complete code examples for database setup, login handling, session sharing, and logout.
Single Sign‑On (SSO) is an authentication technique that allows users to log in once and gain access to multiple applications without re‑entering credentials, simplifying the authentication process and enhancing security.
Implementation Overview
We will develop a simple SSO system consisting of:
1. Main login application
2. Shared authentication service
3. A set of external applications (two in this example) that authenticate via the shared service.
All components run on the same server and use PHP as the programming language.
Implementation Steps
Create database tables
User logs into the main application
Store login information in the shared authentication service
Retrieve login status and access external applications
Handle logout
Create Database Tables
We need two MySQL tables: users and sessions.
Users table stores user information, including username and hashed password:
CREATE TABLE users (
id INT(11) AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL
);Sessions table stores session data:
CREATE TABLE sessions (
id INT(11) AUTO_INCREMENT PRIMARY KEY,
session_id VARCHAR(255) NOT NULL,
user_id INT(11) NOT NULL,
expires_at DATETIME NOT NULL
);User Login in Main Application
The main app provides a login form and validates the submitted username and password. Upon successful verification, it stores the user ID and session information in the database.
Login form:
<form action="login.php" method="post">
<label for="username">Username:</label> <input type="text" name="username" id="username"><br>
<label for="password">Password:</label> <input type="password" name="password" id="password"><br>
<input type="submit" value="Login">
</form>PHP login handling:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
// Check credentials in the database
$db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $db->prepare("SELECT * FROM users WHERE username=:username LIMIT 1");
$stmt->execute(array(':username' => $username));
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
// Store session info in the database
$session_id = session_id();
$user_id = $user['id'];
$expires_at = date('Y-m-d H:i:s', strtotime('+1 day'));
$stmt = $db->prepare("INSERT INTO sessions (session_id, user_id, expires_at) VALUES (:session_id, :user_id, :expires_at)");
$stmt->execute(array(
':session_id' => $session_id,
':user_id' => $user_id,
':expires_at' => $expires_at
));
// Store session ID in a cookie
setcookie('session_id', $session_id, strtotime($expires_at), '/');
// Redirect to an external application
header('Location: http://localhost/external_app_1/index.php');
exit();
} else {
echo 'Invalid username or password';
}
}
?>Storing Login Information in Shared Authentication Service
We use Redis as the shared service and the PHP Predis client to store session data.
<?php
require __DIR__ . '/vendor/autoload.php';
function setSessionData($sessionId, $userId, $expiresAt) {
$redis = new Predis\Client('tcp://127.0.0.1:6379');
$redis->set($sessionId, json_encode(compact('userId', 'expiresAt')));
$redis->expireat($sessionId, strtotime($expiresAt));
}
?>Retrieving Login Status and Accessing External Applications
External apps check the session ID stored in the cookie, retrieve session data from Redis, and verify its validity.
<?php
session_start();
require __DIR__ . '/../vendor/autoload.php';
if (isset($_COOKIE['session_id'])) {
$redis = new Predis\Client('tcp://127.0.0.1:6379');
$sessionId = $_COOKIE['session_id'];
$sessionData = $redis->get($sessionId);
if ($sessionData) {
$sessionData = json_decode($sessionData, true);
if (strtotime($sessionData['expiresAt']) > time()) {
$_SESSION['user_id'] = $sessionData['userId'];
} else {
$redis->del($sessionId);
setcookie('session_id', '', time() - 3600, '/');
header('Location: http://localhost/main_app/login.php');
exit();
}
}
}
if (!isset($_SESSION['user_id'])) {
header('Location: http://localhost/main_app/login.php');
exit();
}
?>Logout Handling
The logout script removes session data from both MySQL and Redis and clears the cookie.
<?php
require __DIR__ . '/../vendor/autoload.php';
if (isset($_COOKIE['session_id'])) {
$redis = new Predis\Client('tcp://127.0.0.1:6379');
$sessionId = $_COOKIE['session_id'];
$redis->del($sessionId);
setcookie('session_id', '', time() - 3600, '/');
}
?>Conclusion
This article demonstrated how to build a PHP‑based SSO system composed of a main login application, a shared authentication service, and multiple external applications, providing complete code examples for each component.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
php Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
