标题:Nest.js Google OAuth Redirect Issue - CORS Error

kx1ctssn  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(164)

我的Nest.js应用程序使用Google OAuth进行身份验证时遇到了一个问题。Nest.js后端运行在端口5000上,前端(Next.js)运行在端口3000上。我已经使用正确的origin URI和redirect URI设置了Google Cloud Console,两者都设置为“http://localhost:3000”。
我在frontend Next.js中遇到以下错误

以下是我的Nest.js Auth Controller、Google OAuth Strategy和Google OAuth Guard的片段:
//Nest.js google oauth策略

export class GoogleOAuthStrategy extends PassportStrategy(Strategy, 'google') {
  constructor(private readonly configService: ConfigService) {
    super({
      clientID: configService.get('googleOAuthClientId'),
      clientSecret: configService.get('googleOAuthClientSecret'),
      callbackURL: configService.get('googleOAuthCallbackURL'),
      scope: ['email', 'profile'],
    });
  }

  async validate(
    accessToken: string,
    refreshToken: string,
    profile: Profile,
    done: VerifyCallback,
  ): Promise<any> {
    const { id, name, emails, photos } = profile;

    const user: User = {
      type: 'individual',
      email: emails[0].value,
      firstName: name.givenName,
      lastName: name.familyName,
      picture: photos[0].value,
      authenticationProviders: [{ name: 'google', id }],
    };

    done(null, user);
  }
}

字符串
//Nest.js google oauth guard

export class GoogleOAuthGuard extends AuthGuard('google') {
  constructor() {
    super({
      accessType: 'offline',
    });
  }
}


//Nest.js auth控制器

export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Get('google')
  @UseGuards(GoogleOAuthGuard)
  async googleAuth() {
    return HttpStatus.OK;
  }

  @Get('google-redirect')
  @UseGuards(GoogleOAuthGuard)
  googleAuthRedirect(
    @Req() req: Request,
    @Res({ passthrough: true }) res: Response,
  ) {
    return this.authService.login(req, res, 'google');
  }
}


//Nest.js验证服务

export class AuthService {
  constructor(
    private readonly configService: ConfigService,
    private readonly usersService: UsersService,
    private readonly jwtService: JwtService,
  ) {}

  async login(req: Request, res: Response, provider: Provider): Promise<void> {
    const user = req.user as User;

    if (!user) {
      throw new NotFoundException(`No user from ${provider}`);
    }

    let userPayload: User;
    let accessTokenPayload: string;

    const foundUser = await this.usersService.findByEmail(user.email);

    if (foundUser) {
      const providerExists = foundUser.authenticationProviders.some(
        (provider) => provider.name === user.authenticationProviders[0].name,
      );

      // User found with different provider
      if (!providerExists) {
        foundUser.authenticationProviders.push(user.authenticationProviders[0]);
        await foundUser.save();
      }

      userPayload = foundUser;
      accessTokenPayload = foundUser._id.toString();
    } else {
      // Save user to mongodb if it does not exists already
      const newUser = await this.usersService.create(user);

      userPayload = newUser;
      accessTokenPayload = newUser._id.toString();
    }

    const accessToken = this.jwtService.sign({ id: accessTokenPayload });

    res.cookie('CARDTRIKA_ACCESS_TOKEN', accessToken, {
      maxAge: this.configService.get('cookieMaxAge'),
      httpOnly: true,
    });

    res.status(HttpStatus.OK).json({
      statusCode: HttpStatus.OK,
      success: true,
      message: 'User information',
      data: userPayload,
    });
  }
}


如果我直接从浏览器向http:localhost:5000/auth/google发出get请求,它会重定向到google API > consent屏幕,然后我可以通过gmail帐户登录,最后可以成功获取用户信息。但Next.js不会发生同样的情况。一旦我发出请求,它就会说CORS错误。

解决方案:

所以,基本上有两个端点。/auth/google/auth/google-redirect。在google控制台上,origin-uri应该是http://localhost:3000,redirect-uri应该设置为http://localhost:3000/auth/google-redirect(无论我们想在前端管理什么)。
现在我们必须从origin localhost:5000请求到/auth/google。所以我做了如下,

const handleLogin = async (method: string) => {
 window.location.replace(`${apiBaseUrl}/auth/${method.toLowerCase()}`);
};


因此,它打开同意屏幕,登录后,它将重定向到http://localhost:3000/auth/google-redirect?code=<some-code-and-other-things>和它的前端我已经管理这个URL页面,并提出了另一个请求,以http://localhost:5000/auth/google-redirect与queryString。所以,在后端现在,谷歌的战略知道它的身份验证,由于它提供的已知代码,并给予我们用户的详细信息。

pvabu6sv

pvabu6sv1#

我很乐意帮助你
我认为问题是你没有在你的后端设置cors域,以允许接收来自其他域的请求。
在 Bootstrap 中,写入app.enableCors({origin: corsDomains}),其中corsDomains是域的数组,(例如http://localhost:3000

相关问题