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

NestJS集成Google Passport OAuth报错:无法解构undefined的profile属性

NestJS集成Google OAuth2出现profile undefined的500错误排查

我正尝试在NestJS中集成Google OAuth2,已配置Google Strategy、Auth控制器及AppModule。访问localhost:8000/api/auth/google完成Google登录后,系统返回500错误,控制台输出提示:Cannot destructure property 'name' of 'profile' as it is undefined,且console.log(profile)结果为undefined。已确认Google Cloud控制台配置正确,现有JWT守卫功能正常,请求帮忙排查问题。

Google Strategy代码

config();

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor(private readonly authService: AuthService) {
    super({
      clientID: process.env.GOOGLE_CLIENT,
      clientSecret: process.env.GOOGLE_SECRET,
      callbackURL: process.env.GOOGLE_REDIRECT,
      passReqToCallback: true,
      scope: ['email', 'profile'],
    });
  }

  async validate(
    accessToken: string,
    refreshToken: string,
    profile: any,
    done: VerifyCallback,
  ): Promise<any> {
    console.log(profile);
    const { name, emails, photos } = profile;
    console.log(profile);
    const user = {
      email: emails[0].value,
      firstName: name.givenName,
      lastName: name.familyName,
      picture: photos[0].value,
      accessToken,
    };
    console.log(user);
    done(null, user);
  }
}

Auth控制器代码

@Get('google')
@Public()
@UseGuards(AuthGuard('google'))
// eslint-disable-next-line @typescript-eslint/no-empty-function
async googleAuth(@Req() req) {}

@Get('redirect')
@Public()
@UseGuards(AuthGuard('google'))
googleAuthRedirect(@Req() req) {
  console.log('callback');
  //return this.appService.googleLogin(req);
}

AppModule代码

@Module({
  imports: [
    ConfigModule.forRoot(),
    EventEmitterModule.forRoot(), // Importez le module ConfigModule
    TypeOrmModule.forRootAsync({
      useFactory: () => ({
        type: isTestEnv ? 'sqlite' : 'mysql',
        host: isTestEnv ? ':memory:' : process.env.DB_HOST,
        port: isTestEnv ? 0 : +process.env.DB_PORT,
        username: isTestEnv ? '' : process.env.DB_USERNAME,
        password: isTestEnv ? '' : process.env.DB_PASSWORD,
        database: isTestEnv ? '' : process.env.DB_DATABASE,
        autoLoadEntities: true,
        synchronize: true,
      }),
    }),
    AuthModule,
    UsersModule,
    RolesModule,
    BoatsModule,
    BoatsMembersModule,
    BoatFacadeModule,
  ],
  controllers: [AppController],
  providers: [
    AppService,

    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
    {
      provide: APP_GUARD,
      useClass: JwtAuthGuard,
    },
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}

问题分析与修复

核心原因

你在Google Strategy的配置中开启了passReqToCallback: true,但未对应调整validate方法的参数顺序。当该选项为true时,Passport会将请求对象req作为validate方法的第一个参数,后续参数依次后移。当前代码中profile参数实际接收的是done回调函数,因此输出为undefined,进而引发解构错误。

修复代码

修改Google Strategy中的validate方法,将req作为第一个参数传入:

async validate(
  req: Request, // 新增请求对象参数,放在首位
  accessToken: string,
  refreshToken: string,
  profile: any,
  done: VerifyCallback,
): Promise<any> {
  console.log(profile); // 此时能正常输出Google返回的用户信息
  const { name, emails, photos } = profile;
  const user = {
    email: emails[0].value,
    firstName: name.givenName,
    lastName: name.familyName,
    picture: photos[0].value,
    accessToken,
  };
  done(null, user);
}

额外检查项

  • 确保process.env.GOOGLE_REDIRECT配置的回调URL与Google Cloud控制台中完全一致(包括协议、端口、路径)
  • 确认已安装必需依赖:@nestjs/passport、passport-google-oauth20、@types/passport-google-oauth20

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:07:07