php 实现单点登录
单点登录(SSO)实现原理
单点登录允许用户通过一次身份验证访问多个关联系统。核心原理是:
- 用户登录后生成全局会话(如Token),其他系统通过验证该会话实现免登录。
- 依赖中央认证服务(如独立的SSO服务器)协调各子系统。
PHP实现方案
基于Token的SSO流程
-
用户访问系统A
系统A检查本地无有效会话,重定向到SSO服务器登录页。 -
SSO服务器验证身份
用户提交凭证,SSO服务器验证通过后生成Token,存储到缓存(如Redis),并返回Token给浏览器(通过Cookie或URL参数)。 -
系统A验证Token
浏览器携带Token访问系统A,系统A向SSO服务器发起验证请求,确认Token有效后建立本地会话。 -
访问系统B
用户访问系统B时,系统B同样重定向到SSO服务器。SSO服务器发现已有全局会话(通过浏览器Cookie),直接返回Token给系统B完成登录。
关键代码示例
SSO服务器生成Token(PHP)
// 生成Token并存储
$token = bin2hex(random_bytes(32));
$redis->setex("sso_token:$token", 3600, json_encode(['user_id' => 123]));
// 设置全局Cookie(跨域需考虑域名)
setcookie('sso_token', $token, time() + 3600, '/', '.example.com');
子系统验证Token(PHP)
// 从请求获取Token
$token = $_COOKIE['sso_token'] ?? $_GET['token'];
// 向SSO服务器发起验证请求
$response = file_get_contents("https://sso.example.com/verify?token=$token");
$data = json_decode($response, true);
if ($data['valid']) {
$_SESSION['user'] = $data['user_id']; // 建立本地会话
}
跨域问题解决
- Cookie跨域:设置Cookie域为父级域名(如
.example.com),确保所有子系统可读取。 - Token传递:通过URL参数或PostMessage(前端跨域通信)传递Token。
安全注意事项
- 使用HTTPS保护Token传输。
- Token设置较短有效期并支持吊销。
- 防范CSRF(如验证Referer或添加CSRF Token)。
扩展方案
- OAuth2/OpenID Connect:标准化协议,适合复杂场景(如第三方登录)。
- SAML:企业级协议,需XML处理支持。
通过以上步骤,可实现基础的PHP单点登录系统,需根据实际需求调整验证逻辑和存储方式。







