在Laravel Jetstream项目中能否通过PHP实现跨站点自动登录功能?
实现方案说明
你要做的是两个自有站点的单点登录功能,仅用PHP配合Laravel自带功能就可以实现,不需要引入额外第三方库,首先明确两个核心原则:
- 绝对不要在跳转链路中明文传递用户密码,也不要通过自动填充登录表单的方式实现,该方案风险极高,容易造成用户凭证泄露
- 不要直接使用固定参数传递用户身份,必须加签名校验防篡改、加有效期防盗用
具体实现逻辑
步骤1:约定共享密钥
两个站点的.env配置文件中新增相同的共享密钥,密钥要使用32位以上的随机字符串,禁止对外泄露:
SSO_SHARED_KEY=这里替换为你自己生成的随机字符串
步骤2:站点1(Laravel Jetstream端)生成带签名的跳转链接
用户点击站点2访问链接时,生成临时有效的签名参数,拼接在跳转链接后,示例代码如下:
// 写在站点1的控制器中 public function getSite2JumpLink() { // 获取当前登录用户ID $userId = auth()->id(); // 生成当前时间戳,用于校验有效期 $timestamp = time(); // 用共享密钥生成签名 $signature = hash_hmac('sha256', $userId . '|' . $timestamp, env('SSO_SHARED_KEY')); // 拼接最终跳转链接 return 'https://你的站点2域名/sso/auto-login?user_id=' . $userId . '&ts=' . $timestamp . '&sign=' . $signature; }
步骤3:站点2新增SSO自动登录路由
站点2新增专门的自动登录处理路由,完成参数校验和用户登录逻辑,示例代码如下(如果站点2也是Laravel开发):
// 站点2的路由对应的控制器方法 public function autoLogin(Request $request) { // 校验必填参数 if (!$request->has(['user_id', 'ts', 'sign'])) { abort(403, '非法请求'); } // 校验链接有效期,这里设置为5分钟内有效 if (time() - $request->input('ts') > 300) { abort(403, '链接已过期,请重新从站点1跳转'); } // 校验签名是否被篡改 $calcSign = hash_hmac('sha256', $request->input('user_id') . '|' . $request->input('ts'), env('SSO_SHARED_KEY')); if (!hash_equals($calcSign, $request->input('sign'))) { abort(403, '签名校验失败'); } // 校验通过后直接登录对应用户 auth()->loginUsingId($request->input('user_id')); // 跳转至站点2的仪表盘页面 return redirect()->to('/dashboard'); }
补充说明
- 如果两个站点的用户数据没有实时同步,可以在签名参数中加入用户邮箱、姓名等基础信息,站点2校验通过后先自动创建/更新对应账号再完成登录
- 如果后续需要对接Facebook、Twitter等第三方平台的登录,再使用Laravel Socialite扩展即可,当前双站点场景不需要额外依赖
- 如果后续需要扩展更多接入站点,可以改用JWT、OAuth2等标准化SSO方案,当前场景用上述签名方案足够简单高效
内容的提问来源于stack exchange,提问作者Jonathan Cruz
相关产品推荐
相关产品推荐

