如何使用php开发单点登录?

dafenqi
2023-12-29 / 0 评论 / 9 阅读 / 正在检测是否收录...

如何使用php开发单点登录?

单点登录(SSO)是一种身份验证技术,它使您在多个应用程序中只需一次登录即可访问。在这种情况下,您不必再次登录每个应用程序,因为您的凭据已在认证服务之间共享。单点登录在实施中大大简化了用户认证过程并提高了安全性。

本文将向您介绍如何使用PHP编写单点登录系统。我们将使用简单的示例来演示实现细节,并附上实现代码。

实现方案

我们将开发一个简单的单点登录系统,该系统由以下组成:

  1. 主登录应用程序
  2. 共享身份验证服务
  3. 一组外部应用程序(本例中为两个),通过共享身份验证服务进行身份验证。

所有应用程序都在同一服务器上运行,并且我们将使用PHP作为我们的编程语言。

实现步骤

以下是我们需要采取的步骤:

  1. 创建数据库表
  2. 用户登录主应用程序
  3. 将登录信息存储在共享身份验证服务中
  4. 获取登录状态并访问外部应用程序
  5. 注销处理

创建数据库表

我们需要在MySQL中创建两个表:用户表和会话表。

用户表将保存用户信息,包括用户名和哈希密码:

CREATE TABLE users (
    id INT(11) AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL
);

会话表将保存会话信息:

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代码:

<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
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
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
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. 一组外部应用程序,通过共享身份验证服务进行身份验证。

我们提供了一个简单的示例来演示实现细节,并附上了实现代码。

0

Deprecated: strtolower(): Passing null to parameter #1 ($string) of type string is deprecated in /www/wwwroot/testblog.58heshihu.com/var/Widget/Archive.php on line 1032

评论 (0)

取消