php实现单点登录
单点登录(SSO)简介
单点登录(Single Sign-On,SSO)是一种身份验证机制,允许用户通过一次登录访问多个相互信任的应用系统。PHP实现SSO的核心在于共享会话或令牌验证。
基于共享会话的实现
共享会话是最简单的SSO实现方式,适用于同一主域下的子域应用。
步骤
-
设置共享会话
在PHP中,通过设置session.cookie_domain为父级域名(如.example.com),使子域(如app1.example.com和app2.example.com)共享会话。ini_set('session.cookie_domain', '.example.com'); session_start(); -
验证登录状态
在每个子域应用中检查会话中的用户信息:session_start(); if (isset($_SESSION['user_id'])) { // 用户已登录 } else { // 跳转到统一登录页 header('Location: https://sso.example.com/login.php'); }
基于令牌(Token)的实现
适用于跨域场景,通过生成并验证令牌实现SSO。
步骤
-
生成令牌
登录成功后,生成一个加密令牌并存储到数据库或缓存中:$token = bin2hex(random_bytes(32)); $_SESSION['token'] = $token; // 存储到数据库(可选) $db->query("INSERT INTO sso_tokens (token, user_id, expires_at) VALUES ('$token', $user_id, NOW() + INTERVAL 1 HOUR)"); -
传递令牌
通过URL参数或POST请求将令牌传递给其他应用:$redirect_url = "https://app2.example.com/verify.php?token=" . urlencode($token); header("Location: $redirect_url"); -
验证令牌
目标应用接收令牌并验证有效性:$token = $_GET['token']; $result = $db->query("SELECT user_id FROM sso_tokens WHERE token = '$token' AND expires_at > NOW()"); if ($result->num_rows > 0) { // 令牌有效,创建本地会话 $_SESSION['user_id'] = $result->fetch_assoc()['user_id']; }
使用OAuth2.0协议
对于更复杂的跨域SSO,可以集成OAuth2.0(如使用league/oauth2-server库)。
步骤
-
安装OAuth2.0库
composer require league/oauth2-server -
配置授权服务器
实现令牌颁发和验证逻辑:use League\OAuth2\Server\AuthorizationServer; // 配置授权服务器(略) -
客户端集成
应用通过OAuth2.0流程获取访问令牌:
// 使用Guzzle等库请求令牌 $response = $http->post('https://sso.example.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'authorization_code', 'code' => $_GET['code'], ], ]);
安全注意事项
- 使用HTTPS传输令牌。
- 设置令牌过期时间(如1小时)。
- 对敏感操作进行二次验证。
以上方法可根据实际需求选择,共享会话适合简单场景,令牌或OAuth2.0适合分布式系统。






