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
相关产品推荐
相关产品推荐

