Loading... # [如何使用php开发单点登录?](https://mp.weixin.qq.com/s/eugIcXEZH-e-f1Vp1341Kw) 单点登录(SSO)是一种身份验证技术,它使您在多个应用程序中只需一次登录即可访问。在这种情况下,您不必再次登录每个应用程序,因为您的凭据已在认证服务之间共享。单点登录在实施中大大简化了用户认证过程并提高了安全性。 本文将向您介绍如何使用PHP编写单点登录系统。我们将使用简单的示例来演示实现细节,并附上实现代码。 ## 实现方案 我们将开发一个简单的单点登录系统,该系统由以下组成: 1. 主登录应用程序 2. 共享身份验证服务 3. 一组外部应用程序(本例中为两个),通过共享身份验证服务进行身份验证。 所有应用程序都在同一服务器上运行,并且我们将使用PHP作为我们的编程语言。 ## 实现步骤 以下是我们需要采取的步骤: 1. 创建数据库表 2. 用户登录主应用程序 3. 将登录信息存储在共享身份验证服务中 4. 获取登录状态并访问外部应用程序 5. 注销处理 ### 创建数据库表 我们需要在MySQL中创建两个表:用户表和会话表。 用户表将保存用户信息,包括用户名和哈希密码: ```mysql CREATE TABLE users ( id INT(11) AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, password VARCHAR(255) NOT NULL ); ``` 会话表将保存会话信息: ```mysql 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 ); ``` ### 用户登录主应用程序 主应用程序的第一步是提供登录功能。这里我们将创建一个简单的登录表单,在用户输入用户名和密码时进行验证。如果验证成功,我们将把用户的ID和会话信息存储在数据库中。 下面是我们的登录表单和PHP代码: ```html <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 session_start(); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $username = $_POST['username']; $password = $_POST['password']; // 在数据库中检查用户名和密码 $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'])) { // 将会话信息存储到数据库中 $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 )); // 将会话ID存储到cookie中 setcookie('session_id', $session_id, strtotime($expires_at), '/'); // 跳转到外部应用程序 header('Location: http://localhost/external_app_1/index.php'); exit(); } else { echo 'Invalid username or password'; } } ?> ``` ### 将登录信息存储在共享身份验证服务中 我们需要为我们的外部应用程序提供一个可以共享的服务,以便可以在主应用程序和外部应用程序之间共享会话信息。 我们用Redis作为我们的共享服务。我们将使用一个 PHP Redis 客户端,它可以与 Redis 服务器进行通信。 这个共享服务将用于存储会话数据,我们需要提供一个使用 PHP Predis 客户端连接到 Redis 并存储数据的函数: ```php <?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)); } ?> ``` ### 获取登录状态并访问外部应用程序 现在,我们需要在外部应用程序中检查用户是否登录。我们将使用会话ID作为标识,这个ID已存储在共享服务中。 如果用户已登录,则我们将允许他们访问外部应用程序。否则,我们将重定向到主应用程序以进行登录。 以下是我们的代码: ```php <?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(); } ?> ``` ### 注销处理 我们还需要提供注销功能,这将删除存储在数据库和共享服务中的会话信息。以下是我们的注销代码: ```php <?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, '/'); } ?> ``` ## 结论 在本文中,我们讨论了如何使用PHP编写单点登录系统,这个系统由以下组成: 1. 主登录应用程序 2. 共享身份验证服务 3. 一组外部应用程序,通过共享身份验证服务进行身份验证。 我们提供了一个简单的示例来演示实现细节,并附上了实现代码。 最后修改:2023 年 12 月 29 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏