如何使用GraphQL与NestJS实现谷歌认证?求方案及文档推荐
NestJS + GraphQL 实现谷歌认证的核心思路
一、依赖准备
先安装必要的包:
npm install @nestjs/passport passport-google-oauth20 @nestjs/graphql @nestjs/jwt passport-jwt npm install -D @types/passport-google-oauth20 @types/passport-jwt
二、配置谷歌OAuth客户端
- 登录谷歌云控制台,创建OAuth 2.0 客户端ID
- 配置授权回调地址:若后端处理回调,设为
http://localhost:3000/auth/google/callback(根据你的服务端口调整) - 记录生成的
clientID和clientSecret,存入环境变量(比如.env文件)
三、实现Google OAuth策略
创建google.strategy.ts:
import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy, VerifyCallback } from 'passport-google-oauth20'; @Injectable() export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { constructor() { super({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: process.env.GOOGLE_CALLBACK_URL, scope: ['email', 'profile'], }); } async validate(accessToken: string, refreshToken: string, profile: any, done: VerifyCallback): Promise<any> { 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); } }
四、Auth模块配置
在auth.module.ts中注册策略和JWT模块:
import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; import { PassportModule } from '@nestjs/passport'; import { GoogleStrategy } from './google.strategy'; import { AuthService } from './auth.service'; import { AuthResolver } from './auth.resolver'; @Module({ imports: [ PassportModule, JwtModule.register({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: '24h' }, }), ], providers: [GoogleStrategy, AuthService, AuthResolver], exports: [AuthService], }) export class AuthModule {}
五、处理认证流程与GraphQL集成
- REST接口处理跳转与回调:谷歌OAuth需要跳转,先在AuthController里提供REST接口:
import { Controller, Get, UseGuards, Redirect, Req } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { AuthService } from './auth.service'; @Controller('auth') export class AuthController { constructor(private authService: AuthService) {} @Get('google') @UseGuards(AuthGuard('google')) async googleAuth() {} @Get('google/callback') @UseGuards(AuthGuard('google')) @Redirect('http://localhost:5173') // 前端地址,跳转回前端并携带token async googleAuthRedirect(@Req() req) { const token = await this.authService.login(req.user); return { url: `http://localhost:5173?token=${token.accessToken}` }; } }
- AuthService生成JWT:
import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class AuthService { constructor(private jwtService: JwtService) {} async login(user: any) { const payload = { email: user.email, sub: user.email }; return { accessToken: this.jwtService.sign(payload), }; } }
- GraphQL认证守卫:创建JWT守卫保护GraphQL接口:
import { ExecutionContext, Injectable } from '@nestjs/common'; import { GqlExecutionContext } from '@nestjs/graphql'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { getRequest(context: ExecutionContext) { const ctx = GqlExecutionContext.create(context); return ctx.getContext().req; } }
- GraphQL Resolver使用守卫:
import { Resolver, Query, UseGuards, Req } from '@nestjs/graphql'; import { JwtAuthGuard } from './jwt-auth.guard'; import { User } from './user.type'; @Resolver() export class AuthResolver { @Query(() => User) @UseGuards(JwtAuthGuard) async getCurrentUser(@Req() req) { return req.user; } }
六、前端对接逻辑
- 提供“谷歌登录”按钮,点击跳转至
http://localhost:3000/auth/google - 用户完成谷歌登录后,后端回调并跳转回前端,携带token
- 前端提取url中的token,存入localStorage
- 后续GraphQL请求时,在请求头中添加
Authorization: Bearer ${token}
文档推荐
- NestJS官方Passport集成文档
- NestJS官方GraphQL指南
- Passport-google-oauth20官方文档
- NestJS官方示例仓库中的认证模块示例
内容的提问来源于stack exchange,提问作者Parth_Choksi
相关产品推荐
相关产品推荐

