导读:本期聚焦于小伙伴创作的《PHP如何实现单点登录功能?跨域名共享会话ticket验证方案详解》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《PHP如何实现单点登录功能?跨域名共享会话ticket验证方案详解》有用,将其分享出去将是对创作者最好的鼓励。

单点登录(SSO)的核心目标是让用户在一个系统登录后,访问其他关联系统无需重复输入账号密码即可自动完成身份校验。在PHP开发中,跨域名场景下由于浏览器同源策略限制,无法直接共享Cookie,因此需要借助ticket验证机制实现会话同步。

PHP如何实现单点登录功能?跨域名共享会话ticket验证方案详解

单点登录核心原理

跨域名单点登录的核心逻辑分为三个角色:认证中心(SSO Server)业务系统A(Client A)业务系统B(Client B)。整体流程如下:

  • 用户访问Client A,未登录则跳转至SSO Server登录页
  • 用户在SSO Server完成登录,服务端生成全局会话和唯一ticket
  • SSO Server将ticket作为参数回跳至Client A的回调地址
  • Client A携带ticket向SSO Server发起校验请求,验证通过后创建本地会话
  • 用户访问Client B时,重复上述ticket校验流程,无需再次登录

核心数据表设计

首先需要设计存储用户会话和ticket的数据表,这里给出核心表结构:

表名字段说明
sso_ticketticket唯一票据字符串,用于校验身份
user_id关联的用户ID
expire_timeticket过期时间戳
is_usedticket是否已使用,0未使用1已使用
sso_sessionsession_id全局会话ID
user_id关联的用户ID
expire_time全局会话过期时间戳

关键功能代码实现

1. ticket生成逻辑

用户登录成功后,生成唯一且有过期时间的ticket,存储到数据库并返回给业务系统:

<?php
/**
 * 生成单点登录ticket
 * @param int $userId 用户ID
 * @param int $expire 过期时长(秒),默认300秒
 * @return string
 */
function generateSsoTicket($userId, $expire = 300) {
    // 生成随机ticket字符串
    $ticket = md5(uniqid($userId . time(), true));
    $expireTime = time() + $expire;
    // 存储ticket到数据库
    $pdo = new PDO('mysql:host=127.0.0.1;dbname=sso_db;charset=utf8', 'root', '123456');
    $sql = 'INSERT INTO sso_ticket (ticket, user_id, expire_time, is_used) VALUES (?, ?, ?, 0)';
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$ticket, $userId, $expireTime]);
    return $ticket;
}
?>

2. 业务系统校验ticket逻辑

业务系统接收到SSO Server返回的ticket后,向SSO Server发起校验请求,验证通过后创建本地会话:

<?php
/**
 * 校验ticket并创建本地会话
 * @param string $ticket 待校验的ticket
 * @param string $ssoVerifyUrl SSO Server校验接口地址
 * @return bool
 */
function verifyTicketAndLogin($ticket, $ssoVerifyUrl) {
    if (empty($ticket)) {
        return false;
    }
    // 向SSO Server发起校验请求
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $ssoVerifyUrl . '?ticket=' . $ticket);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec($ch);
    curl_close($ch);
    $result = json_decode($response, true);
    if ($result['code'] != 200) {
        return false;
    }
    // 校验通过,创建本地会话
    session_start();
    $_SESSION['user_id'] = $result['data']['user_id'];
    $_SESSION['login_time'] = time();
    return true;
}

// 使用示例
$ticket = $_GET['ticket'] ?? '';
$verifyUrl = 'http://sso.ipipp.com/verify_ticket';
if (verifyTicketAndLogin($ticket, $verifyUrl)) {
    echo '登录成功,欢迎访问业务系统A';
} else {
    echo '登录失败,请重新登录';
}
?>

3. SSO Server校验ticket接口

SSO Server接收业务系统的校验请求,验证ticket有效性并返回用户ID:

<?php
// SSO Server ticket校验接口
header('Content-Type: application/json; charset=utf-8');
$ticket = $_GET['ticket'] ?? '';
if (empty($ticket)) {
    echo json_encode(['code' => 400, 'msg' => 'ticket不能为空']);
    exit;
}
$pdo = new PDO('mysql:host=127.0.0.1;dbname=sso_db;charset=utf8', 'root', '123456');
// 查询ticket信息
$sql = 'SELECT * FROM sso_ticket WHERE ticket = ? AND is_used = 0 AND expire_time > ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$ticket, time()]);
$ticketInfo = $stmt->fetch(PDO::FETCH_ASSOC);
if (empty($ticketInfo)) {
    echo json_encode(['code' => 401, 'msg' => 'ticket无效或已过期']);
    exit;
}
// 标记ticket已使用,避免重复使用
$updateSql = 'UPDATE sso_ticket SET is_used = 1 WHERE id = ?';
$pdo->prepare($updateSql)->execute([$ticketInfo['id']]);
// 返回用户信息
echo json_encode([
    'code' => 200,
    'msg' => '校验成功',
    'data' => ['user_id' => $ticketInfo['user_id']]
]);
?>

注意事项

  • ticket必须设置较短的过期时间,且只能使用一次,避免被截获后重复使用
  • SSO Server和业务系统之间的接口通信建议添加签名校验,防止请求被伪造
  • 全局会话和本地会话的过期时间需要做好同步,避免出现状态不一致问题
  • 跨域名场景下,SSO Server的域名需要和业务系统的域名做好DNS解析配置,确保网络互通
该方案适用于中小型系统的跨域名单点登录需求,若系统规模较大,可结合Redis存储会话信息,提升读写性能。

PHP单点登录跨域名共享会话ticket验证修改时间:2026-06-17 06:39:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。