PHP 语言 开发简单的单点登录系统

PHP阿木 发布于 14 天前 4 次阅读


简单单点登录系统(SSO)的PHP实现

单点登录(Single Sign-On,SSO)是一种用户认证机制,允许用户在多个应用程序中使用同一组凭证进行登录。本文将围绕PHP语言,介绍如何开发一个简单的单点登录系统。

单点登录系统在大型企业或组织中非常有用,因为它可以简化用户登录过程,提高安全性,并减少管理成本。我们将使用PHP和MySQL来构建一个简单的SSO系统。

系统设计

我们的SSO系统将包括以下组件:

1. 认证服务器(Auth Server):负责处理用户登录请求,生成会话令牌,并存储用户会话信息。

2. 资源服务器(Resource Server):需要用户认证的服务器,通过认证服务器验证用户身份。

3. 用户数据库:存储用户信息和会话信息。

技术栈

- PHP

- MySQL

- JSON Web Tokens (JWT)

- OAuth 2.0

实现步骤

1. 创建数据库

我们需要创建一个MySQL数据库来存储用户信息和会话信息。

sql

CREATE DATABASE sso;

USE sso;

CREATE TABLE users (


id INT AUTO_INCREMENT PRIMARY KEY,


username VARCHAR(50) NOT NULL,


password VARCHAR(255) NOT NULL


);

CREATE TABLE sessions (


id INT AUTO_INCREMENT PRIMARY KEY,


user_id INT NOT NULL,


token VARCHAR(255) NOT NULL,


FOREIGN KEY (user_id) REFERENCES users(id)


);


2. 用户认证服务器

认证服务器负责处理用户登录请求,验证用户凭证,并生成JWT令牌。

php

<?php


// auth_server.php

// 连接数据库


$mysqli = new mysqli("localhost", "root", "password", "sso");

// 检查连接


if ($mysqli->connect_error) {


die("Connection failed: " . $mysqli->connect_error);


}

// 检查POST请求


if ($_SERVER['REQUEST_METHOD'] === 'POST') {


$username = $_POST['username'];


$password = $_POST['password'];

// 验证用户凭证


$stmt = $mysqli->prepare("SELECT id, password FROM users WHERE username = ?");


$stmt->bind_param("s", $username);


$stmt->execute();


$stmt->bind_result($id, $hashed_password);


$stmt->fetch();

if (password_verify($password, $hashed_password)) {


// 用户凭证验证成功,生成JWT令牌


$token = bin2hex(random_bytes(32));


$stmt = $mysqli->prepare("INSERT INTO sessions (user_id, token) VALUES (?, ?)");


$stmt->bind_param("is", $id, $token);


$stmt->execute();

// 返回JWT令牌


echo json_encode(['token' => $token]);


} else {


// 用户凭证验证失败


echo json_encode(['error' => 'Invalid credentials']);


}

$stmt->close();


$mysqli->close();


}


?>


3. 资源服务器

资源服务器需要验证JWT令牌,以确保用户有权访问受保护的资源。

php

<?php


// resource_server.php

// 连接数据库


$mysqli = new mysqli("localhost", "root", "password", "sso");

// 检查连接


if ($mysqli->connect_error) {


die("Connection failed: " . $mysqli->connect_error);


}

// 检查请求头中的Authorization字段


$auth_header = $_SERVER['Authorization'];


if (preg_match('/Bearer (.+)/', $auth_header, $matches)) {


$token = $matches[1];

// 验证JWT令牌


$stmt = $mysqli->prepare("SELECT user_id FROM sessions WHERE token = ?");


$stmt->bind_param("s", $token);


$stmt->execute();


$stmt->bind_result($user_id);


$stmt->fetch();

if ($user_id) {


// JWT令牌验证成功,用户有权访问受保护资源


echo json_encode(['message' => 'Access granted']);


} else {


// JWT令牌验证失败


echo json_encode(['error' => 'Invalid token']);


}

$stmt->close();


$mysqli->close();


} else {


// 没有提供Authorization字段


echo json_encode(['error' => 'Authorization header missing']);


}


?>


4. 测试

现在,我们可以使用Postman或其他HTTP客户端工具来测试我们的SSO系统。

1. 向认证服务器发送登录请求,获取JWT令牌。

2. 将JWT令牌添加到资源服务器的请求头中,尝试访问受保护资源。

总结

本文介绍了如何使用PHP和MySQL实现一个简单的单点登录系统。虽然这个示例非常基础,但它提供了一个SSO系统的基础框架。在实际应用中,您可能需要添加更多的安全性和功能,例如令牌刷新、会话过期和跨域资源共享(CORS)。

请注意,为了简化示例,我们省略了错误处理和安全性最佳实践。在生产环境中,您应该使用HTTPS、密码哈希、错误日志记录和适当的异常处理来确保系统的安全性。