跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何在两个独立的 Laravel 应用间实现统一认证(基于 Sanctum)

本文介绍如何利用 laravel sanctum 在物理隔离、不同代码仓库的两个 laravel 应用(app a 与 app b)之间安全共享用户会话与认证状态,支持跨域 token 验证与无状态登录。 本文介绍如何利用 laravel sanctum 在物理隔离、不同代码仓库的两个 laravel 应用(app a 与 app b)之间安全共享用户会话与认证状态,支持跨域 token 验证与无状态登录。 Laravel Sanctum 原生设计支持两种主要认证模式: Token-based API 认证 (适用于 SPA 或移动客户端)和 Cookie-based Web 认证 (适用于传统服务端渲染应用)。当两个 Laravel 应用需共享同一套用户体系并实现“一次登录、多端通行”时,推荐采用 Cookie + CSRF + Sanctum API Token 的混合方案 ,前提是它们共享同一根域名(如 app-a.example.com 和 app-b.example.com)或可配置为信任的同源/跨域环境。 ✅ 前提条件 两个应用均使用 Laravel ≥ 8.0 + Sanctum ≥ 2.0; 共享同一数据库(用户表共用),或通过 UserProvider 自定义同步逻辑(如 JWT 中继、OAuth2 中心化授权); App A 作为认证中心(Auth Server),App B 作为受信客户端(Resource Client); 若跨子域,需统一配置 SESSION_DOMAIN=.example.com 和 SANCTUM_STATEFUL_DOMAINS=app-a.example.com,app-b.example.com。 ? 关键配置步骤(以 App A 为认证源) 在 App A 中启用 Sanctum 并暴露登录接口
// routes/api.php (App A) use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; Route::post('/login', function (Request $request) { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); if (Auth::attempt($credentials)) { $user = Auth::user(); $token = $user->createToken('app-b-access')->plainTextToken; return response()->json(['token' => $token]); } return response()->json(['message' => 'Unauthorized'], 401); });
App B 配置 Sanctum 为 API 消费者 在 .env 中指定 App A 的 API 地址,并禁用本地 Session 登录(改用 Token 认证):
# .env (App B) SANCTUM_STATEFUL_DOMAINS=app-b.example.com APP_A_API_URL=https://app-a.example.com
在 config/sanctum.php 中确保 stateful 匹配前端域名:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1,app-b.example.com')),
App B 登录逻辑(调用 App A 接口) Laravel 13.2.0 PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。 下载
// LoginController@authenticate (App B) public function authenticate(Request $request) { $response = Http::asForm()->post(config('app.app_a_api_url').'/api/login', [ 'email' => $request->email, 'password' => $request->password, ]); if ($response->successful()) { $token = $response->json()['token']; // 将 token 存入本地 session 或 localStorage(SPA 场景) session(['sanctum_token' => $token]); return redirect()->intended('/dashboard'); } return back()->withErrors(['email' => 'Invalid credentials']); }
API 请求携带 Token(App B 调用自身受保护接口时)
// App B 中受保护路由示例 Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); // 自动解析 token 并加载用户 });
⚠️ 注意事项 ❌ 不要直接共享 SESSION_DRIVER=database 或 redis 实例来“复用 Session”——这违背无状态设计且存在安全与扩展风险; ✅ 推荐将 App A 作为唯一认证入口,App B 仅负责 Token 校验(Sanctum 默认支持 Bearer Token 解析); ? 生产环境务必启用 HTTPS,禁用 APP_DEBUG=true,并对 /api/login 加速率限制(throttle:api); ? 若两应用完全跨域(如 a.com ↔ b.net),则必须使用 Sanctum 的 Token 认证模式 (非 Cookie 模式),并通过 Authorization: Bearer {token} 头传递,此时 stateful 配置无效,需手动在中间件中校验。 ✅ 总结 通过 Sanctum 的灵活 Token 机制,两个独立 Laravel 应用可安全、解耦地实现统一认证体验。核心在于: App A 提供标准化登录接口并签发 Token;App B 消费该 Token 并交由 Sanctum 中间件统一验证 。无需引入 OAuth2 服务器等重型组件,即可达成轻量、可控、符合 Laravel 生态的最佳实践。

相关文章