如何在Nest.js项目的Swagger UI中配置Google登录?
需求可实现,以下是具体实现步骤
1. 配置Google OAuth客户端
- 登录Google Cloud控制台,创建OAuth 2.0客户端ID
- 设置授权重定向URI为你的API回调地址,比如
http://localhost:3000/api/auth/google/callback - 记录生成的
clientId和clientSecret,后续在NestJS中使用
2. 在NestJS中实现Google OAuth登录流程
首先安装依赖:
npm install @nestjs/passport passport-google-oauth20 passport @nestjs/jwt
2.1 配置Google OAuth策略
创建google.strategy.ts:
import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy, VerifyCallback } from 'passport-google-oauth20'; import { ConfigService } from '@nestjs/config'; @Injectable() export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { constructor(configService: ConfigService) { super({ clientID: configService.get('GOOGLE_CLIENT_ID'), clientSecret: configService.get('GOOGLE_CLIENT_SECRET'), callbackURL: 'http://localhost:3000/api/auth/google/callback', 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, // 可直接使用Google的accessToken,或生成自定义JWT }; done(null, user); } }
2.2 创建Auth控制器
创建auth.controller.ts,实现登录跳转和回调端点:
import { Controller, Get, UseGuards, Redirect, Req, Query } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Controller('api/auth') export class AuthController { // 触发Google登录跳转 @Get('google') @UseGuards(AuthGuard('google')) async googleLogin() {} // Google登录回调处理 @Get('google/callback') @UseGuards(AuthGuard('google')) @Redirect('/api/docs', 302) async googleLoginCallback(@Req() req) { // 将Google返回的token作为查询参数带回Swagger UI const token = req.user.accessToken; return { url: `/api/docs?token=${token}` }; } }
2.3 配置AuthModule
在auth.module.ts中注册策略和控制器:
import { Module } from '@nestjs/common'; import { AuthController } from './auth.controller'; import { GoogleStrategy } from './google.strategy'; import { PassportModule } from '@nestjs/passport'; import { JwtModule } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; @Module({ imports: [ PassportModule, JwtModule.registerAsync({ useFactory: (configService: ConfigService) => ({ secret: configService.get('JWT_SECRET'), signOptions: { expiresIn: '1d' }, }), inject: [ConfigService], }), ], controllers: [AuthController], providers: [GoogleStrategy], }) export class AuthModule {}
3. 自定义Swagger UI添加登录按钮
通过自定义JavaScript给Swagger UI添加登录按钮,并自动处理回调带回的token:
在main.ts中修改Swagger配置:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; async function bootstrap() { const app = await NestFactory.create(AppModule); const config = new DocumentBuilder() .setTitle('API文档') .setDescription('API接口文档') .setVersion('1.0') .addBearerAuth() // 开启Bearer授权支持 .build(); const document = SwaggerModule.createDocument(app, config); // 自定义JS逻辑 const customJs = ` window.addEventListener('load', function() { // 添加Google登录按钮到Swagger头部 const header = document.querySelector('.swagger-ui .topbar'); const loginBtn = document.createElement('button'); loginBtn.textContent = 'Google登录'; loginBtn.className = 'btn btn-primary'; loginBtn.style.marginLeft = '10px'; loginBtn.onclick = () => window.location.href = '/api/auth/google'; header.appendChild(loginBtn); // 自动填充URL中的token到授权框 const urlParams = new URLSearchParams(window.location.search); const token = urlParams.get('token'); if (token) { const authModal = document.getElementById('auth-modal'); const bearerInput = authModal.querySelector('input[type="text"]'); bearerInput.value = token; // 自动提交授权 authModal.querySelector('.btn.authorize').click(); // 清除URL中的token参数 window.history.replaceState({}, document.title, window.location.pathname); } }); `; SwaggerModule.setup('api/docs', app, document, { customJs: customJs, }); await app.listen(3000); } bootstrap();
4. 测试流程
- 启动NestJS项目,访问
http://localhost:3000/api/docs - 点击新增的「Google登录」按钮,跳转至Google登录页面完成授权
- 授权成功后自动返回Swagger UI,token会自动填充到授权框
- 此时即可访问需要Bearer授权的受保护接口
内容的提问来源于stack exchange,提问作者Ernesto Murrugarra
相关产品推荐
相关产品推荐

