You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PHP实现免凭证跨站用户身份认证方案咨询

跨站点身份互通(单点登录SSO)落地实现方案

核心实现逻辑

你描述的场景属于典型的**中央认证源单点登录(SSO)**逻辑,不需要引入复杂的第三方组件,基于你现有的PHP+MySQL技术栈就可以快速实现,核心思路是将主站作为唯一的身份校验入口,所有关联站点的身份验证都委托给主站完成,通过带时效的单次授权码完成身份信息的安全传递。

具体落地步骤

1. 主站侧改造&开发内容

原有注册、登录逻辑不需要做大幅调整,只需要新增4个能力即可:

  • 统一登录页适配回调逻辑:在原有登录地址增加redirect_uri参数接收,用户登录成功后,自动跳转回该回调地址,同时携带临时授权码code
  • 临时授权码生成逻辑:用户登录成功后,生成一个10分钟内有效的随机字符串作为code,和当前登录用户ID、过期时间、关联站点域名(校验用)一起存入MySQL的sso_auth_code表,避免授权码被恶意冒用
  • 授权码校验接口:提供公共接口接收关联站点传递的code,校验code是否有效、是否过期、来源域名是否匹配,校验通过后返回用户公开信息(用户名、头像等),同时立即销毁该code(单次有效,防止复用)
    简化的主站校验接口示例代码:
// 主站 sso_check_code.php
header('Content-Type: application/json');
$code = $_GET['code'] ?? '';
$client_domain = $_SERVER['HTTP_REFERER'] ? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) : '';

// 数据库查询授权码信息
$stmt = $pdo->prepare("SELECT user_id, expire_time, allow_domain FROM sso_auth_code WHERE code = ?");
$stmt->execute([$code]);
$auth_info = $stmt->fetch(PDO::FETCH_ASSOC);

// 校验失败直接返回
if (!$auth_info || time() > $auth_info['expire_time'] || $auth_info['allow_domain'] != $client_domain) {
    echo json_encode(['code' => 403, 'msg' => '授权无效']);
    exit;
}

// 获取用户信息
$user_stmt = $pdo->prepare("SELECT username FROM users WHERE id = ?");
$user_stmt->execute([$auth_info['user_id']]);
$user = $user_stmt->fetch(PDO::FETCH_ASSOC);

// 销毁授权码,禁止复用
$pdo->prepare("DELETE FROM sso_auth_code WHERE code = ?")->execute([$code]);
echo json_encode(['code' => 200, 'data' => $user]);
  • 登录状态静默校验接口:给关联站点提供免跳转的登录状态检测能力,方便后续关联站点静默刷新用户身份状态。

2. 关联站点侧开发内容

只需要新增全局身份校验逻辑即可,不需要改动原有业务代码:

  • 全局中间件校验本地登录状态:所有页面请求进来先校验本地Session是否有用户登录信息,有则直接使用;没有则进入SSO认证流程
  • 认证跳转+授权码校验逻辑:如果本地没有登录状态,先判断请求参数里是否有主站返回的code,有则请求主站校验接口获取用户信息写入本地Session,没有则直接跳转到主站登录页,同时携带当前页面地址作为回调参数
    简化的关联站全局校验示例代码:
// 关联站 全局公共校验逻辑
session_start();
if (!isset($_SESSION['username'])) {
    // 存在主站返回的授权码则先校验
    if (isset($_GET['code'])) {
        $code = $_GET['code'];
        // 请求主站校验接口获取用户信息
        $user_info = file_get_contents("https://主站域名/sso_check_code.php?code=" . $code);
        $user_info = json_decode($user_info, true);
        if ($user_info['code'] == 200) {
            $_SESSION['username'] = $user_info['data']['username'];
            // 移除URL里的code参数,刷新当前页面
            header('Location: ' . strtok($_SERVER["REQUEST_URI"], '?'));
            exit;
        }
    }
    // 没有授权码或者校验失败,跳转主站登录
    $redirect_uri = urlencode("https://关联站域名" . $_SERVER['REQUEST_URI']);
    header("Location: https://主站域名/login.php?redirect_uri=" . $redirect_uri . "&client_id=提前约定的站点标识");
    exit;
}

3. 必须做的安全优化

  • 所有回调地址redirect_uri必须在主站做白名单校验,禁止跳转到未授权的站点,避免钓鱼攻击
  • 临时授权码必须是短时效、单次有效,禁止设置长期有效的授权码
  • 主站和关联站的接口请求如果涉及敏感信息,建议改用POST方式加签名校验,不要用明文GET传参
  • 如果后续需要扩展更多关联站点、多端登录能力,可以直接对接标准OAuth2.0或者JWT协议,底层逻辑和上述实现思路完全一致。

内容的提问来源于stack exchange,提问作者Star_Amazing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:09:00