如何让NextAuth使用NestJS后端自定义JWT令牌实现谷歌登录?
NestJS + NextAuth 谷歌登录:解决"missing code verifier"并使用后端自定义令牌
一、解决"missing code verifier"错误
你当前把谷歌OAuth的request_uri直接指向NestJS后端,但NextAuth在谷歌登录流程中使用了**PKCE(Proof Key for Code Exchange)**机制,code_verifier是由NextAuth前端生成并保存的,后端直接处理谷歌回调时没有这个验证器,所以触发报错。
正确做法是让NextAuth先处理谷歌的回调,再在NextAuth的回调函数中调用你的NestJS后端接口,完成用户信息同步和自定义令牌获取。
修改NextAuth的GoogleProvider配置,移除自定义的request_uri,使用默认回调地址:
GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, // 移除authorization中的request_uri配置,使用NextAuth默认回调 }),
二、集成NestJS后端的自定义令牌与用户信息
接下来通过NextAuth的回调体系对接后端,实现以下逻辑:谷歌登录成功后,将用户信息传给后端完成创建/更新,获取后端生成的自定义令牌和数据库用户信息,最终让NextAuth存储这些后端数据而非谷歌原始返回值。
1. 配置NextAuth的回调函数
修改[...nextauth].ts中的callbacks配置:
export default NextAuth({ providers: [GoogleProvider(...)], session: { strategy: "jwt", // 使用JWT模式存储自定义令牌和用户信息 }, callbacks: { async signIn({ profile }) { // 调用NestJS后端接口,传递谷歌用户核心信息 const response = await fetch(`${process.env.BACKEND_URL}/auth/google/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ googleId: profile.sub, email: profile.email, name: profile.name, avatar: profile.picture, }), }); if (!response.ok) return false; // 后端校验失败,拒绝登录 // 接收后端返回的自定义令牌和数据库用户信息 const { accessToken, user: dbUser } = await response.json(); // 将后端数据挂载到user对象,供后续JWT回调使用 return { accessToken, dbUser }; }, async jwt({ token, user }) { // 登录时将后端令牌和用户信息存入JWT if (user) { token.accessToken = user.accessToken; token.user = user.dbUser; } return token; }, async session({ session, token }) { // 将后端数据注入前端可访问的session session.accessToken = token.accessToken; session.user = token.user; return session; }, }, });
2. 配置NestJS后端接口
在NestJS中创建接收谷歌用户信息的接口,完成用户创建/更新并返回自定义JWT:
@Public() @Post('google/login') async googleLogin(@Body() googleUserDto: GoogleUserDto) { // 1. 根据谷歌ID查找或创建用户 let user = await this.userService.findOneByGoogleId(googleUserDto.googleId); if (!user) { user = await this.userService.create({ googleId: googleUserDto.googleId, email: googleUserDto.email, name: googleUserDto.name, avatar: googleUserDto.avatar, }); } // 2. 生成后端自定义JWT令牌 const accessToken = this.jwtService.sign({ userId: user.id }); // 3. 返回令牌和数据库用户信息 return { accessToken, user: { id: user.id, email: user.email, name: user.name, // 按需添加其他用户字段 }, }; }
3. 清理冗余后端代码
你之前写的google/callback接口可以直接移除,因为现在NextAuth已经接管了谷歌OAuth的回调流程,无需后端直接处理。
关键注意事项
- 不要修改谷歌OAuth的
request_uri,NextAuth会自动处理PKCE流程,彻底避免"missing code verifier"错误 - 通过
signIn回调对接后端,确保用户数据同步到后端数据库,同时获取自定义令牌 - 利用
jwt和session回调,将后端的用户信息和令牌注入到前端可访问的会话中
内容的提问来源于stack exchange,提问作者Mohamed Elsobky
相关产品推荐
相关产品推荐

