如何为Laravel Sanctum认证的SPA添加Laravel Socialite登录
我用Vue3对接Laravel Sanctum做认证,常规账号密码登录流程完全正常,但接入Google Socialite登录后遇到了问题:用户通过Google OAuth登录完成,后端回调重定向回前端后,前端没有拿到Sanctum会话Cookie,导致后续访问受保护接口时被踢回登录页。手动创建Cookie也无效,Chrome里只显示“Provisional headers are shown”,看不到设置的Cookie。
问题根源
OAuth重定向流程是「前端→API后端→Google→API后端→前端」,API到前端的重定向如果涉及跨域(比如前端域名app.local,后端api.app.local),Cookie的传递会受浏览器的SameSite策略、域名匹配、加密规则等限制。手动创建的Cookie参数和Laravel会话系统自动生成的不一致,浏览器会直接拒绝接收。
解决方案
1. 先核对核心配置
确保.env和config里的会话、Sanctum配置正确:
.env中设置:SESSION_DOMAIN=.app.local # 根域名,让前后端子域名都能共享Cookie SANCTUM_STATEFUL_DOMAINS=app.local # 允许的前端域名 SESSION_SECURE_COOKIE=false # 本地HTTP环境设为false,线上HTTPS设为true SESSION_DRIVER=database # 不要用array驱动,否则会话不会持久化config/session.php中确认:'same_site' => 'lax', 'http_only' => true,
2. 简化回调路由代码,不要手动创建Cookie
Laravel的会话系统会自动处理Cookie的生成和附加,不需要手动创建。Auth::login()和session()->regenerate()已经完成了会话的创建和更新,直接重定向即可:
public function callback(Request $request): \Illuminate\Http\RedirectResponse { // 验证state参数,防止CSRF(可选但建议) if ($request->state !== session()->pull('state')) { abort(403, 'Invalid state parameter'); } $googleUser = Socialite::driver('google')->user(); // 业务逻辑:根据Google用户信息查找或创建本地用户 $user = User::firstOrCreate( ['email' => $googleUser->getEmail()], ['name' => $googleUser->getName(), 'google_id' => $googleUser->getId()] ); Auth::login($user); session()->regenerate(); // 防止会话固定攻击 // 直接重定向到前端仪表盘,Laravel会自动带上会话Cookie return redirect('http://app.local/dashboard'); }
3. 前端确保请求携带Cookie
在Vue3的请求库(比如Axios)里开启withCredentials,这样后续请求会自动带上Cookie:
// 在Axios全局配置里添加 axios.defaults.withCredentials = true; // 或者单个请求里设置 axios.get('/api/protected-endpoint', { withCredentials: true });
4. 本地开发的浏览器设置
如果是本地开发遇到Cookie不生效,检查Chrome的Cookie设置:
- 打开
chrome://settings/cookies - 开启「允许所有Cookie」(仅本地开发用,线上建议保持默认)
为什么手动创建Cookie没用?
Laravel的会话Cookie是经过加密的,并且严格遵循config/session.php里的参数(比如加密、HttpOnly、SameSite、域名)。手动创建的Cookie没有经过Laravel的加密流程,或者参数和配置不一致,浏览器会认为是不安全的Cookie而拒绝存储。
内容的提问来源于stack exchange,提问作者qotsa42

