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.

php Courses
php Courses
php Courses
Implementing Single Sign-On (SSO) with PHP: A Step-by-Step Guide

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

redismysqlAuthenticationPHPSSO
php Courses
Written by

php Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.