
本文详解如何利用 laravel sanctum 在物理隔离、不同代码仓库的两个 laravel 应用(app a 与 app b)之间共享用户会话与认证状态,支持跨域 sso 场景,兼顾安全性与工程可行性。
本文详解如何利用 laravel sanctum 在物理隔离、不同代码仓库的两个 laravel 应用(app a 与 app b)之间共享用户会话与认证状态,支持跨域 sso 场景,兼顾安全性与工程可行性。
在微前端或分布式 Laravel 架构中,常需让多个独立部署的 Laravel 应用(如管理后台、客户门户、API 中台)共用同一套用户体系。Laravel Sanctum 虽原生面向 SPA 认证设计,但通过合理配置,完全可支撑「App A 认证后,App B 自动登录」的跨应用单点登录(SSO)流程——关键不在于 Sanctum 是否“原生支持”,而在于如何统一认证源、共享 Session 或 Token 上下文。
✅ 核心前提:共用认证数据源与基础配置
两个应用必须共享同一套用户数据和密钥环境:
- 共用数据库(推荐):App A 和 App B 连接同一个 users 表(或通过数据库视图/同步机制保证用户 ID 一致);
- 共享 APP_KEY:确保 APP_KEY 完全一致(用于加密 session、cookie 签名等),否则 Sanctum 的 tokenable_type + tokenable_id 验证将失败;
-
统一 SESSION_DOMAIN 与 Cookie 设置(若同主域):
# .env of both apps SESSION_DRIVER=cookie SESSION_DOMAIN=.example.com # 注意开头的点,支持子域共享 SANCTUM_STATEFUL_DOMAINs=app-a.example.com,app-b.example.com
⚠️ 注意:若 App A 与 App B 部署在完全不同主域(如 a.com 和 b.net),则无法共享 Cookie,此时应放弃 Session-based 方案,改用 Token-based SSO 流程(见下文)。
✅ 方案一:同主域 Cookie 共享(推荐用于子域场景)
适用于 admin.example.com(App A)与 portal.example.com(App B)等同根域名部署。
- App A(认证发起方):正常使用 Sanctum 登录,返回带 XSRF-TOKEN 与 laravel_session 的响应;
- App B(受信消费方):在前端请求时自动携带该域下的有效 cookie(由浏览器自动注入);
- App B 后端验证:无需额外鉴权逻辑,直接使用 auth:sanctum 中间件即可识别已登录用户:
// routes/api.php (App B)
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user(); // 自动解析来自共享 cookie 的用户
});✅ 优势:零侵入、无缝体验、符合 Sanctum 设计哲学;
❌ 限制:严格依赖同主域(.example.com)及正确配置 SESSION_DOMAIN 和 SANCTUM_STATEFUL_DOMAINS。
✅ 方案二:跨域 Token 中继(适用于完全异构域名)
当 App A(login.a.com)与 App B(app.b.org)无域名交集时,需引入轻量级 Token 中继机制:
- App A 登录成功后,生成一个短期有效的、签名的一次性访问令牌(JWT 或 Sanctum Plain Token):
// In App A, after login $token = $user->createToken('app-b-access')->plainTextToken; return response()->json(['redirect_url' => 'https://app.b.org/login?token=' . $token]); - App B 提供 /login 接口接收 token,验证签名并建立本地 Sanctum 会话:
// In App B, controller public function login(Request $request) { $token = $request->query('token'); [$id, $hash] = explode('|', $token, 2); $user = User::find($id); if (!$user || !Hash::check($hash, $user->getAuthPassword())) { abort(401); } $device = substr(request()->userAgent(), 0, 255); $sanctumToken = $user->createToken($device)->plainTextToken; return response()->json(['message' => 'Login OK'])->withCookie( cookie('laravel_session', $sanctumToken, 60, null, '.b.org', true, true) ); }
✅ 优势:突破域名限制,可控性强;
⚠️ 注意:需自行保障 token 传输安全(HTTPS + 一次性 + 短期过期)、防范 CSRF 重放,建议配合 state 参数校验。
? 总结与最佳实践
- ✅ 首选同主域 Cookie 共享方案:配置简单、安全可靠、体验最优;
- ✅ 避免重复用户表同步:优先共库或使用 Laravel Passport/Sanctum API Token 作为中心认证服务;
- ❌ 不要尝试修改 Sanctum 源码绕过 tokenable_type 校验——这破坏了模型绑定安全性;
- ? 生产环境务必启用 HTTPS,并设置 SESSION_SECURE=true、SANCTUM_STATEFUL_DOMAINS 显式声明可信域名;
- ? 开发调试时,可用 php artisan sanctum:install 确保 Sanctum 数据表与中间件注册正确。
通过合理架构设计与 Sanctum 的灵活运用,两个独立 Laravel 应用完全可以构建健壮、安全、用户体验一致的联合认证体系。










