php如何实现单点登录功能_php跨域名共享会话ticket验证方案

爱谁谁
发布: 2025-11-26 20:28:02
原创
617人浏览过
单点登录通过中心认证服务实现跨域身份验证,用户在SSO Server登录后获取一次性ticket,经重定向传递至客户端,客户端通过验证接口校验ticket并建立本地会话,利用Redis存储ticket信息并设置过期时间,结合HTTPS、来源校验等机制保障安全,登出时由中心通知各客户端销毁会话。

php如何实现单点登录功能_php跨域名共享会话ticket验证方案

单点登录(SSO)的核心是让用户在一个系统中登录后,访问其他关联的系统时无需重复登录。在 PHP 中实现跨域名的 SSO,关键在于如何安全地共享用户身份凭证(ticket),尤其是在不同域名之间无法直接共享 Cookie 的情况下。

基本原理:基于中心认证服务的 Ticket 验证

搭建一个独立的认证中心(SSO Server),所有子系统(Client A、Client B 等)都信任该中心。用户首次访问任意子系统时,被重定向到 SSO Server 登录。登录成功后,SSO Server 发放一个一次性 ticket,并通过回调方式通知原系统完成身份确认。

典型流程如下:
  • 用户访问 client-a.com,未登录,跳转至 sso-server.com?redirect=client-a.com/callback
  • 用户在 sso-server.com 输入账号密码登录
  • 登录成功,sso-server.com 生成唯一 ticket(如 tkt-abc123),存储在服务端(Redis 推荐)并设置有效期
  • 重定向回 client-a.com/callback?ticket=tkt-abc123
  • client-a.com 收到 ticket,向 sso-server.com/api/validate 发起请求验证 ticket 合法性
  • sso-server 验证通过后返回用户信息,并标记该 ticket 已使用(防止重放攻击)
  • client-a.com 创建本地会话,用户登录成功

跨域名共享的关键:Ticket 传递与验证

由于 Cookie 不可跨域共享(如 client-a.com 无法读取 client-b.com 的 session),必须依赖中心服务器进行身份仲裁。ticket 是一次性的,通过 URL 参数传递,安全性较高。

实现要点:
  • Ticket 存储: 使用 Redis 存储 ticket 与用户信息的映射,设置自动过期时间(如 5 分钟)
  • 验证接口: SSO Server 提供 /api/validate?t=xxx 接口,返回 JSON 格式数据(是否有效、用户 ID、用户名等)
  • HTTPS 必须启用: 所有通信需走 HTTPS,防止 ticket 被窃听
  • Referer 或签名校验: 可增加来源域名白名单或请求签名,防止伪造验证请求

PHP 实现示例片段

SSO Server 生成 ticket(登录成功后):

立即学习PHP免费学习笔记(深入)”;

巧文书
巧文书

巧文书是一款AI写标书、AI写方案的产品。通过自研的先进AI大模型,精准解析招标文件,智能生成投标内容。

巧文书 281
查看详情 巧文书
$ticket = 'tkt_' . bin2hex(random_bytes(16));
$userId = 123;
// 存入 Redis,5分钟过期
$redis->setex($ticket, 300, json_encode(['user_id' => $userId, 'used' => false]));
header('Location: ' . $_GET['redirect'] . '?ticket=' . $ticket);

Client 端验证 ticket:

if (isset($_GET['ticket'])) {
  $ticket = $_GET['ticket'];
  $response = file_get_contents("https://sso-server.com/api/validate?t={$ticket}");
  $data = json_decode($response, true);
  if ($data['valid'] && !$data['used']) {
    $_SESSION['user_id'] = $data['user_id'];
    // 标记 ticket 已使用(由 server 完成)
  }
}

SSO Server 验证接口(/api/validate):

$t = $_GET['t'];
$data = $redis->get($t);
if (!$data) {
  echo json_encode(['valid' => false]); exit;
}
$info = json_decode($data, true);
if ($info['used']) {
  echo json_encode(['valid' => false]); exit;
}
// 标记为已使用,防止重放
$info['used'] = true;
$redis->setex($t, 300, json_encode($info)); // 更新状态
echo json_encode(['valid' => true, 'user_id' => $info['user_id']]);

登出处理

登出需要通知所有已登录的客户端。可在 SSO Server 记录用户的 active sessions,登出时向各 client 发起异步登出请求(如 client-a.com/sso/logout?token=xxx),各 client 销毁本地 session。

基本上就这些。核心是信任中心 + 一次性 ticket + 安全传输。不复杂但容易忽略细节,比如 ticket 过期、重放、来源校验等。

以上就是php如何实现单点登录功能_php跨域名共享会话ticket验证方案的详细内容,更多请关注php中文网其它相关文章!

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号