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

Laravel Sanctum+Socialite谷歌OAuth:登录后session的user_id为空

问题分析与解决方案

核心原因

你的问题主要出在会话中间件缺失、操作顺序错误以及Socialite配置不匹配会话认证场景这几个点上:

  1. 路由未加载会话相关中间件:api.php中的路由默认使用api中间件组,该组不包含StartSession、EncryptCookies等维护会话必需的中间件,导致Auth::login($user)无法将用户ID写入sessions表。
  2. 会话与登录操作顺序颠倒:先执行session()->regenerate()再登录用户,会导致新生成的空会话无法关联用户信息。
  3. 不必要的stateless()配置:基于Cookie的会话认证需要维护状态,stateless()会禁用Socialite的会话状态存储,干扰后续会话绑定逻辑。

具体修复步骤

1. 调整路由中间件

将OAuth相关路由切换到web中间件组(或在api.php中手动添加会话中间件),因为web中间件默认包含会话所需的所有组件:

// api.php 中修改路由组
Route::group(['prefix' => 'v2/auth', 'middleware' => ['web']], function () {
    Route::get('google/callback', [SocialiteController::class, 'googleCallback']);
    Route::get('google/redirect', [SocialiteController::class, 'googleRedirect']);
});

同时在app/Http/Middleware/VerifyCsrfToken.php中放行OAuth路由,避免CSRF拦截:

protected $except = [
    '/v2/auth/google/*',
];

2. 修正登录与会话操作顺序

先完成用户登录,再重新生成会话ID(防止会话固定攻击),确保新会话关联用户:

public function googleCallback()
{
    // 移除 stateless()
    $googleUser = Socialite::driver('google')->user();

    $user = $this->authRepository->show($googleUser->email);

    if (!$user) {
        $request = (object)[
            'email' => $googleUser->getEmail(),
            'password' => Str::random(40)
        ];

        $user = $this->authService->register($request);
    }

    // 先登录用户,绑定到当前会话
    Auth::login($user);
    // 再重新生成会话ID
    session()->regenerate();

    return redirect('http://localhost:3000/auth/callback?authStatus=' . true . '&email=' . urlencode($user->email));
}

3. 配置Sanctum与会话域名

确保config/sanctum.php的stateful数组包含前端域名:

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    '%s%s',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
    env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),

在.env中设置会话与Sanctum域名:

SANCTUM_STATEFUL_DOMAINS=localhost:3000
SESSION_DOMAIN=.localhost

4. 前端请求配置

Nuxt3中确保请求携带Cookie,在nuxt.config.ts中配置:

export default defineNuxtConfig({
  modules: ['@nuxtjs/axios'],
  axios: {
    baseURL: 'http://localhost:8000/api',
    credentials: true
  }
})

验证

完成修改后重新走OAuth流程:

  1. 查看sessions表,确认新会话的user_id已关联对应用户ID;
  2. 前端调用/api/user(需用auth:sanctum中间件保护),确认返回用户信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:46:16