NestJS中为Swagger接口添加Basic Auth认证失败求助
解决Fastify版NestJS中Swagger Basic Auth认证失效问题
1. 安装依赖
先安装@fastify/basic-auth插件:
npm install @fastify/basic-auth # 或 yarn add @fastify/basic-auth
2. 修改main.ts添加Basic Auth配置
在注册helmet、compression等插件之后,setupSwagger之前,添加认证相关代码:
首先引入插件:
import fastifyBasicAuth from '@fastify/basic-auth'
然后注册插件并配置验证逻辑(建议从环境变量读取账号密码,避免硬编码):
// 注册Basic Auth插件 await app.register(fastifyBasicAuth, { validate: async (username, password) => { // 替换为你的验证规则,示例用环境变量存储合法账号密码 const validUser = process.env.SWAGGER_USERNAME || 'admin' const validPass = process.env.SWAGGER_PASSWORD || 'admin123' if (username !== validUser || password !== validPass) { throw new Error('Invalid credentials') } }, authenticate: true, // 自动触发浏览器弹出账号密码输入框 }) // 给Swagger相关路由绑定认证拦截 // 根据你的setupSwagger实际配置调整路径,比如/docs、/swagger等 const swaggerPaths = ['/docs', '/docs/*', '/api-docs', '/api-docs/*'] swaggerPaths.forEach(path => { app.get(path, { preHandler: app.basicAuth }) app.post(path, { preHandler: app.basicAuth }) // 覆盖Swagger可能存在的POST请求 })
3. 核心注意事项
- 注册顺序:必须在
setupSwagger之前完成fastify-basic-auth的注册和路由绑定,否则Swagger路由已创建无法被拦截。 - 路径匹配:确认
swaggerPaths包含你实际使用的Swagger访问路径,比如如果setupSwagger配置的是/swagger,就将路径改为/swagger和/swagger/*。 - 兼容性:若与helmet的CSP规则冲突,可在helmet配置中放宽Swagger相关资源的限制。
完整修改后的main.ts片段
// ... 其他导入语句 import fastifyBasicAuth from '@fastify/basic-auth' async function bootstrap() { const PORT = process.env.PORT || 3010 const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter()) // ... 现有代码:版本控制、CORS、全局管道、全局过滤器等 // 注册helmet、compression插件 await app.register(fastifyHelmet, { /* 你的原有配置 */ }) await app.register(compression, { encodings: ['gzip', 'deflate'] }) // 添加Basic Auth配置 await app.register(fastifyBasicAuth, { validate: async (username, password) => { const validUser = process.env.SWAGGER_USERNAME || 'admin' const validPass = process.env.SWAGGER_PASSWORD || 'admin123' if (username !== validUser || password !== validPass) { throw new Error('Invalid credentials') } }, authenticate: true, }) // 拦截Swagger路由 const swaggerPaths = ['/docs', '/docs/*', '/api-docs', '/api-docs/*'] swaggerPaths.forEach(path => { app.get(path, { preHandler: app.basicAuth }) app.post(path, { preHandler: app.basicAuth }) }) // 初始化Swagger setupSwagger(app) // ... 监听端口、启用 shutdown hooks等代码 } bootstrap()
内容的提问来源于stack exchange,提问作者Aditya Vyas
相关产品推荐
相关产品推荐

