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

如何将React OAuth与NestJS Google OAuth认证对接

解决React前端对接NestJS Google OAuth2登录的问题

问题背景

已在NestJS中通过Passport配置Google认证策略,后端(localhost:8000)核心代码如下:

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

@Get('redirect')
@ApiOkResponse()
@ApiUnauthorizedResponse({
  description: 'Wrong password.',
})
@ApiNotFoundResponse({
  description: 'User with this email not found.',
})
@Public()
@UseGuards(AuthGuard('google'))
async googleAuthRedirect(@Res() response: any, @Req() req) {
  const accessToken = await this.authService.signInWithGoogle(req.user);
  return response.status(HttpStatus.OK).json(accessToken);
}

直接访问localhost:8000/google可正常完成Google登录并获取access_token,但使用@react-oauth/google编写的React前端(localhost:3000)仅能完成Google登录并在控制台输出凭证,无法触发后端接口调用。Google云控制台已配置重定向URI为localhost:8000/redirect。

前端现有代码:

import React, { useState } from 'react';
import { Header } from '../components/Header';
import { LoginForm } from '../components/LoginFormComponent';
import { GoogleLogin } from '@react-oauth/google';
import axios from 'axios';

const Login = () => {
  const handleGoogleLoginSuccess = async (response: any) => {
    console.log(response);
  };

  const handleGoogleLoginFailure = () => {
    console.error('Google login error');
    // Gérer les erreurs de connexion ici
  };

  return (
    <div>
      {/* Votre contenu de connexion */}
      <GoogleLogin
        onSuccess={handleGoogleLoginSuccess}
        onError={handleGoogleLoginFailure}
      />
    </div>
  );
};

export default Login;

修改方案

1. 前端改用后端引导的授权流程

放弃@react-oauth/google的客户端侧登录逻辑,直接引导用户跳转到后端的Google授权入口,复用已有的后端认证流程:

import React, { useEffect, useState } from 'react';
import { Header } from '../components/Header';
import { LoginForm } from '../components/LoginFormComponent';

const Login = () => {
  const [accessToken, setAccessToken] = useState<string | null>(null);

  // 组件挂载时解析URL中的token参数
  useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const token = urlParams.get('token');
    if (token) {
      setAccessToken(token);
      localStorage.setItem('access_token', token);
      // 登录成功后跳转首页
      window.location.href = '/';
    }
  }, []);

  // 触发Google登录跳转
  const handleGoogleLogin = () => {
    window.location.href = 'http://localhost:8000/google';
  };

  return (
    <div>
      {/* 其他登录内容 */}
      <button onClick={handleGoogleLogin}>使用Google登录</button>
    </div>
  );
};

export default Login;

2. 后端调整回调逻辑,传递token到前端

修改googleAuthRedirect方法,将生成的access_token通过重定向传递回前端:

@Get('redirect')
@ApiOkResponse()
@ApiUnauthorizedResponse({ description: '认证失败' })
@ApiNotFoundResponse({ description: '未找到该邮箱对应的用户' })
@Public()
@UseGuards(AuthGuard('google'))
async googleAuthRedirect(@Res() response: any, @Req() req) {
  const accessToken = await this.authService.signInWithGoogle(req.user);
  // 重定向回前端并携带token参数
  return response.redirect(`http://localhost:3000/login?token=${accessToken.access_token}`);
}

3. 配置NestJS跨域支持

在main.ts中添加CORS配置,允许前端域名的请求:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // 配置CORS
  app.enableCors({
    origin: 'http://localhost:3000',
    credentials: true,
  });
  await app.listen(8000);
}
bootstrap();

4. 补充Google云控制台配置

在OAuth2客户端ID设置中添加前端域名的授权来源:

  • 授权JavaScript来源:新增http://localhost:3000
  • 重定向URI保持http://localhost:8000/redirect不变

内容的提问来源于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 04:56:16