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

如何让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:17:58