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

NestJS Passport谷歌认证仅回调路由可获取req.user如何解决

问题1:req.user仅谷歌认证回调路由可获取的解决方案

只有被@UseGuards(AuthGuard('google'))装饰的路由才会触发Passport的谷歌校验逻辑,临时挂载req.user,请求结束后该数据就会销毁,要全路由复用需要配置会话持久化,步骤如下:

  • 安装会话依赖
npm install express-session @types/express-session
  • 根入口main.ts配置全局会话
import * as session from 'express-session';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(session({
    secret: '自定义的会话加密密钥',
    resave: false,
    saveUninitialized: false,
    cookie: { maxAge: 24 * 60 * 60 * 1000 } // 会话有效期可自定义,这里是1天
  }));
  // 其余原有配置
  await app.listen(4000);
}
  • AuthModule中开启Passport会话支持,配置用户序列化/反序列化逻辑
import { PassportModule, PassportSerializer } from '@nestjs/passport';

@Module({
  imports: [
    PassportModule.register({ session: true }),
    // 其余原有导入
  ],
  providers: [AuthService, GoogleStrategy],
  controllers: [AuthController]
})
export class AuthModule {
  constructor(
    private readonly passport: PassportSerializer,
    private readonly authService: AuthService
  ) {
    // 序列化:用户校验通过后将唯一标识存入会话
    this.passport.serializeUser((user: any, done) => {
      done(null, user.id);
    });
    // 反序列化:每次请求从会话取标识查询完整用户信息,挂载到req.user
    this.passport.deserializeUser(async (id: string, done) => {
      const user = await this.authService.findUserById(id); // 自行实现根据ID查用户的方法
      done(null, user);
    });
  }
}
  • 需要获取req.user的路由添加会话守卫即可,示例:
@Get('login')
@UseGuards(AuthGuard('session'))
async info(@Req() req, @Res() res) {
  console.log(req.user) // 可正常获取
}

如果不想用会话存储,也可以在回调路由生成JWT返回前端,后续请求携带JWT,通过JWT守卫校验挂载req.user,逻辑一致。

问题2:谷歌回调跨域报错的解决方案

该报错和Nest的CORS配置无关,核心原因是谷歌的OAuth授权页面本身不支持跨域AJAX请求,你原生Express正常运行大概率是原生逻辑中前端用页面跳转而非AJAX请求登录接口,修复方案如下:

  • 前端不要用XMLHttpRequest/fetch请求/api/v1/auth/google接口,改为直接页面跳转,示例:
<!-- 方案1:a标签跳转 -->
<a href="http://localhost:4000/api/v1/auth/google">谷歌登录</a>
// 方案2:JS触发跳转
window.location.href = 'http://localhost:4000/api/v1/auth/google'
  • 回调路由拿到用户信息后不要返回JSON,重定向回前端地址,可将用户标识/JWT拼在参数中传给前端,示例:
@Get('callback')
@UseGuards(AuthGuard('google'))
async googleAuthRedirect(@Res() res, @Req() req) {
  res.redirect('http://localhost:3000?userId=' + req.user.id)
}

如果需要无跳转登录,可前端接入谷歌OAuth JS SDK拿到授权码后传给后端校验,不需要走后端重定向流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:57:00