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

NestJS问题:排除/api/docs路由后仍无法绕过Basic Auth中间件

解决NestJS Basic Auth中间件无法排除Swagger路由的问题

问题根源

  • Swagger路由不止一个:除了/api/docs,Swagger UI还会请求/swagger-ui.html、/api-json等静态资源路由,仅排除单个路径会导致这些资源被拦截
  • 中间件异常返回错误:当前中间件直接return new UnauthorizedException(),这种方式在Express中间件中无法被Nest的异常处理器正确处理
  • 路径匹配精度不足:字符串路径的精确匹配无法覆盖带查询参数的请求(如/api/docs?foo=bar)

修复步骤

1. 修正中间件的异常处理逻辑

将直接返回异常改为抛出异常,确保Nest能正确处理认证失败场景:

import type { NestMiddleware } from '@nestjs/common';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import type { NextFunction, Request, Response } from 'express';

import { ApiConfigService } from '@shared/config.service';

@Injectable()
export class BasicAuthMiddleware implements NestMiddleware {
  constructor(private configService: ApiConfigService) {}

  use(req: Request, res: Response, next: NextFunction) {
    if (req.headers['authorization']) {
      const authorization = req.headers['authorization'];
      const basic = authorization.match(/^Basic (.+)$/);

      if (!basic) {
        throw new UnauthorizedException();
      }

      const credentials = Buffer.from(basic[1], 'base64').toString('utf-8');
      const { username, password } = this.configService.basicAuthConfig;

      if (credentials !== `${username}:${password}`) {
        throw new UnauthorizedException();
      }

      return next();
    }
    throw new UnauthorizedException();
  }
}

2. 扩展排除的Swagger相关路由

使用正则表达式匹配所有Swagger相关路径,确保覆盖所有静态资源:

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
// 其他导入...

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(BasicAuthMiddleware)
      .exclude(
        /^\/api\/docs(\/.*)?$/,
        /^\/swagger-ui(\/.*)?$/,
        /^\/api(-json)?$/
      )
      .forRoutes({
        path: '*',
        method: RequestMethod.ALL
      });
  }
}

3. (可选)使用路径对象精确匹配

若不想用正则,可配置多个路径对象实现精确排除:

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(BasicAuthMiddleware)
      .exclude(
        { path: '/api/docs', method: RequestMethod.GET },
        { path: '/swagger-ui', method: RequestMethod.GET },
        { path: '/swagger-ui/*', method: RequestMethod.GET },
        { path: '/api-json', method: RequestMethod.GET }
      )
      .forRoutes({
        path: '*',
        method: RequestMethod.ALL
      });
  }
}

验证方式

启动服务后,直接访问/api/docs应能正常加载Swagger UI且无需凭证;访问其他业务路由(如/api/users)则会触发Basic Auth验证。

内容的提问来源于stack exchange,提问作者dokichan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:05:20