是否可以添加身份验证以访问 NestJS 的 Swagger Explorer

jos*_*c89 27 typescript swagger-ui openapi nestjs

我目前在 NestJS 项目中使用 Swagger,并且启用了资源管理器:

main.js

const options = new DocumentBuilder()
    .setTitle('My App')
    .setSchemes('https')
    .setDescription('My App API documentation')
    .setVersion('1.0')
    .build()

const document = SwaggerModule.createDocument(app, options)
SwaggerModule.setup('docs', app, document, {
    customSiteTitle: 'My App documentation',
})
Run Code Online (Sandbox Code Playgroud)

有了这个,资源管理器可以访问,/docs这是我所期望的。但我想知道是否可以向资源管理器添加任何身份验证层,因此只接受某些请求。

我想让这个资源管理器在生产中可以访问,但仅限于经过身份验证的用户。

提前致谢 :)

pra*_*t17 14

更新

根据最近DocumentBuilder方法的变化,这对我有用。分享给正在使用新版本的人。

const options = new DocumentBuilder()
.setTitle('My API')
.setDescription('API used for testing purpose')
.setVersion('1.0.0')
.setBasePath('api')
.addBearerAuth(
  { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' },
  'access-token',
)
.build();

const document = SwaggerModule.createDocument(app, options);
Run Code Online (Sandbox Code Playgroud)

更新另外,请@ApiBearerAuth()在您的控制器功能上使用添加身份验证。

@Get('/test')
@ApiBearerAuth()
Run Code Online (Sandbox Code Playgroud)

access-token是 swagger 文档中供参考的名称。您在标头中的令牌将按如下方式传递:

curl -X GET "http://localhost:3004/test" -H "accept: application/json" -H "Authorization: Bearer test-token"
Run Code Online (Sandbox Code Playgroud)

  • 不知怎的,这对我不起作用,标头不会应用于请求-curl输出保持不变-curl -X GET“http://localhost:3000/unit-type”-H“accept:*/*” (5认同)
  • 这说明了端点的安全性,而不是招摇本身。 (3认同)
  • @Jacobdo 您能在 swagger 文档中看到端点上的锁定图标吗?您可以单击它并传递访问令牌,如果没有,则需要在控制器函数中添加`@ApiBearerAuth()`,请参阅更新的答案 (2认同)
  • 只是 `.addBearerAuth({ in: 'header', type: 'http' })` (2认同)
  • 问题是关于保护对 swagger 页面本身的访问,而不是在路由 swagger 显示上显示身份验证选项。请参阅我的答案,了解如何使用 HTTP 基本身份验证来实际保护您的“/docs”端点。 (2认同)

小智 10

只需将.addBearerAuth()(不带任何参数)添加到您的 swagger 选项中

@ApiBearerAuth()你的控制器方法

const options = new DocumentBuilder()
    .setTitle('My App')
    .setSchemes('https')
    .setDescription('My App API documentation')
    .setVersion('1.0')
    .addBearerAuth()
    .build()

Run Code Online (Sandbox Code Playgroud)


Rez*_*eza 8

这是针对 APIKEY 而非持有者

如果有人到达此帖子并寻找apiKey(而不是持有者),您需要遵循此操作

在 main.ts 中

    const options = new DocumentBuilder()
        .setTitle('CMOR')
        .setDescription('CMOR API documentation')
        .setVersion('1.0')
        .addServer('/api')
        .addApiKey({
            type: 'apiKey', // this should be apiKey
            name: 'api-key', // this is the name of the key you expect in header
            in: 'header',
        }, 'access-key' // this is the name to show and used in swagger
        ) 
        .build();
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器或方法中

@ApiTags('analyzer')
@ApiSecurity('access-key') // this is the name you set in Document builder
@Controller('analyzer')
export class ScreenAnalyzerController {
Run Code Online (Sandbox Code Playgroud)


小智 8

在@nestjs/swagger 4.0 版中更新了重大/API 更改。

嗨,花了很多尝试和失败才能做到这一点。代码中的注释对于理解很重要。这些名称相互依赖才能发挥作用。

主文件

    const options = new DocumentBuilder()
        .setTitle('my-title')
        .setDescription('my-descirption')
        .setVersion('1.0')
        .addBearerAuth(
          {
            type: 'http',
            scheme: 'bearer',
            bearerFormat: 'JWT',
            name: 'JWT',
            description: 'Enter JWT token',
            in: 'header',
          },
          'JWT-auth', // This name here is important for matching up with @ApiBearerAuth() in your controller!
        )
        .build();
      const document = SwaggerModule.createDocument(app, options);
      SwaggerModule.setup('api', app, document);
Run Code Online (Sandbox Code Playgroud)

在您的控制器中,您执行以下操作(注意 @ApiBearerAuth() 使用与 main.ts 中 swagger 选项上的名称相同的名称):

app.controller.ts

    @Roles(Role.Admin)
      @UseGuards(JwtAuthGuard, RolesGuard)
      @ApiTags('Admin')
      @ApiOperation({ summary: 'Get admin section' })
      @Get('admin')
      @ApiBearerAuth('JWT-auth') // This is the one that needs to match the name in main.ts
      getAdminArea(@Request() req) {
        return req.user;
      }
Run Code Online (Sandbox Code Playgroud)

希望这可以节省我花时间了解发生了什么的人。

  • 呃,终于。这是唯一一篇真正解释得足够好,足以让我的白痴大脑明白的文章。可以添加的另一件事是“@ApiBearerAuth('JWT-auth')”也可以用作整个控制器类的装饰器。像 `@Controller('users') @ApiBearerAuth('JWT-auth') export class UserController {...}` 您也可以将 `.addSecurityRequirements('JWT-auth')` 放在 `.build()` 之前`main.ts` 将该身份验证方案应用于整个系统。 (4认同)

Kiw*_*ian 8

使用带有 Express 的 NestJS 通过 HTTP Basic Auth 保护对 Swagger 的访问

首先运行,npm i express-basic-auth然后将以下内容添加到您的main.{ts,js}

// add import
import * as basicAuth from 'express-basic-auth';

// ...

// Sometime after NestFactory add this to add HTTP Basic Auth
app.use(
    ['/docs', '/docs-json'],
    basicAuth({
        challenge: true,
        users: {
            yourUserName: 'p4ssw0rd',
        },
    }),
);


// Your code
const options = new DocumentBuilder()
    .setTitle('My App')
    .setSchemes('https')
    .setDescription('My App API documentation')
    .setVersion('1.0')
    .build()

const document = SwaggerModule.createDocument(app, options)
SwaggerModule.setup('docs', app, document, {
    customSiteTitle: 'My App documentation',
})

// ...
Run Code Online (Sandbox Code Playgroud)

有了这个,你将在任何/docs路由上得到一个 HTTP 基本身份验证提示。我们也必须/docs-json明确命名,以保护生成的 JSON OpenAPI 文件。

您不应该将凭据放在您的代码/存储库中,而应该放在您的.env和 通过ConfigService访问。

我首先在这里看到了这个解决方案。

  • 因为还有一个 /docs-yaml 端点,所以我最终指定了 `['/docs*'`] (2认同)

Bar*_*rki 5

下面的例子运行得很好

.addBearerAuth({ in: 'header', type: 'http' })

in您应该告诉道具中令牌的位置在哪里

由于您覆盖了默认选项,因此您应该传递type

  const options = new DocumentBuilder()
    .setTitle('Api docs for mobile')
    .setDescription('The api docs for the mobile application')
    .setVersion('1.0')
    .addBearerAuth({ in: 'header', type: 'http' })
    .build();
Run Code Online (Sandbox Code Playgroud)

实施addBearerAuth

  const options = new DocumentBuilder()
    .setTitle('Api docs for mobile')
    .setDescription('The api docs for the mobile application')
    .setVersion('1.0')
    .addBearerAuth({ in: 'header', type: 'http' })
    .build();
Run Code Online (Sandbox Code Playgroud)


Ali*_*fat 5

添加.addBearerAuth()到您的招摇选项后,您应该添加@ApiBearerAuth()到您的控制器或其方法。

注意:为了在刷新页面后将令牌保留在浏览器中的 swagger UI 中,您应该在 swagger 选项中进行设置:

SwaggerModule.setup('docs', app, document, {
    swaggerOptions: {
        persistAuthorization: true, // this
    },
});
Run Code Online (Sandbox Code Playgroud)