如何将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
相关产品推荐
相关产品推荐

