是否可以添加身份验证以访问 NestJS 的 Swagger Explorer
Is it possible to add Authentication to access to NestJS' Swagger Explorer
我目前在我的 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',
})
有了这个,资源管理器可以在 /docs
中访问,这正是我所期望的。但我想知道是否可以向资源管理器添加任何身份验证层,因此只接受某些请求。
我想让这个资源管理器在生产环境中可以访问,但仅限经过身份验证的用户。
提前致谢:)
对于遇到类似挑战的任何人,您可以在 Nestjs 中向您的 Swagger UI 添加身份验证,如下所示。
const options = new DocumentBuilder()
.setTitle('Sample Project API')
.setDescription('This is a sample project to demonstrate auth in Swagger UI')
.setVersion('1.0')
.addTag('Nestjs Swagger UI')
.setContactEmail('your_contact@mail.com')
.addBearerAuth('Authorization', 'header', 'basic')
.setBasePath('api')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('docs', app, document);
所以 .addBearerAuth 需要 3 个参数(密钥名称、位置、身份验证类型)。授权类型可以是 basic
、bearer
或 apikey
更新
根据最近对 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);
更新另外,请在您的控制器功能上使用@ApiBearerAuth()
添加授权。
@Get('/test')
@ApiBearerAuth()
access-token
是 swagger 文档中供参考的名称。您在 header 中的令牌将按如下方式传递:
curl -X GET "http://localhost:3004/test" -H "accept: application/json" -H "Authorization: Bearer test-token"
只需将 .addBearerAuth()
(不带任何参数)添加到您的 swagger 选项中
和@ApiBearerAuth()
到您的控制器方法
const options = new DocumentBuilder()
.setTitle('My App')
.setSchemes('https')
.setDescription('My App API documentation')
.setVersion('1.0')
.addBearerAuth()
.build()
以下示例运行良好
.addBearerAuth({ in: 'header', type: 'http' })
你应该告诉 in
prop
中令牌的位置在哪里
并且由于您覆盖了默认选项,因此您应该传递 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();
addBearerAuth
实施
addBearerAuth(options = {
type: 'http'
}, name = 'bearer') {
this.addSecurity(name, Object.assign({ scheme: 'bearer', bearerFormat: 'JWT' }, options));
return this;
}
这是 APIKEY 不持有者
万一有人到达此 post 并寻找 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();
然后在你的控制器或方法中
@ApiTags('analyzer')
@ApiSecurity('access-key') // this is the name you set in Document builder
@Controller('analyzer')
export class ScreenAnalyzerController {
根据@nestjs/swagger 4.0 版中的 breaking/API 更改进行了更新。
嗨,
花了很多尝试和失败才能做到这一点。
代码中的注释是理解的重要内容。这些名称相互依赖才能发挥作用。
main.ts
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);
然后在您的控制器中执行以下操作(注意@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;
}
希望这可以节省一些人我理解发生了什么的时间。
使用 NestJS 和 Express 通过 HTTP 基本身份验证保护对 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',
})
// ...
有了这个,您将在任何 /docs
路由上收到带有 HTTP 基本身份验证提示的提示。我们也必须明确命名 /docs-json
,以保护生成的 JSON OpenAPI 文件。
您不应将凭据放在 code/repository 中,而应放在 .env
中并通过 ConfigService.
访问
我第一次看到这个解决方案here。
您可以通过添加 addApiKey
或 addBearerAuth
示例来完成此问题的其他答案。
在我这边,我可以添加 OAuth2 身份验证
@nestjs/swagger3** 和@nestjs/swagger4**
在实现上有一些区别
For the @nestjs/swagger3**
const options = new DocumentBuilder()
.setTitle('API')
.setDescription('API')
.setVersion('1.0')
.setSchemes('https', 'http')
.addOAuth2('implicit', AUTH_URL, TOKEN_URL)
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup(swaggerPath, app, document, {
swaggerOptions: {
oauth2RedirectUrl: REDIRECT_URL, // after successfully logging
oauth: {
clientId: CLIENT_ID,
},
},
});
addOAuth2 还支持密码、应用程序和访问代码等流程
For the @nestjs/swagger4**
const options = new DocumentBuilder()
.setTitle('API')
.setDescription('API description')
.setVersion(version)
.addServer(host)
.addOAuth2(
{
type: 'oauth2',
flows: {
implicit: {
authorizationUrl: AUTH_URL + `?nonce=${getRandomNumber(9)}`, // nonce parameter is required and can be random, for example nonce=123456789
tokenUrl: TOKEN_URL,
scopes: SCOPES, // { profile: 'profile' }
},
},
},
'Authentication'
)
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup(swaggerPath, app, document, {
swaggerOptions: {
oauth2RedirectUrl: REDIRECT_URL, // after successfully logging
oauth: {
clientId: CLIENT_ID,
},
},
});
对于无法通过上述答案解决的任何人。
这是我添加不记名令牌的方法
const options = new DocumentBuilder()
.setTitle('My API')
.setDescription('My api')
.setVersion('1.0.0')
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
name: 'JWT',
description: 'Enter JWT token',
in: 'header',
},
'token'
)
.build();
添加后不要忘记添加装饰器@ApiBearerAuth('token')
还有一件事要注意,.addBearerAuth({...}, 'token')
方法中的第二个参数需要添加到装饰器中,这样只有您才能在 curl 请求中看到授权。
@Controller('api')
@ApiBearerAuth('token')
你也可以将它留空 @ApiBearerAuth()
并从
中删除第二个参数
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
name: 'JWT',
description: 'Enter JWT token',
in: 'header',
})
NestJS 文档需要改进
根据之前的答案,您可能会看到此错误(如果您想使用 express-basic-auth
模块
Type 'typeof expressBasicAuth' has no call signatures.
Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead
对于这种情况,您可以在 main.ts
中使用 .default
import * as basicAuth from 'express-basic-auth';
async function bootstrap() {
app.use(['/docs'], basicAuth.default({
challenge: true,
users: {
[process.env.SWAGGER_USERNAME]: process.env.SWAGGER_PASSWORD,
},
}));
const options = new DocumentBuilder()
.setTitle('api')
.setDescription('API description')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('docs', app, document);
}
在你的 main.ts 文件中添加这个
const config = new DocumentBuilder()
.setTitle('App title')
.setDescription("Api description")
.setVersion('1.0')
.addTag('ApiTag')
.setContact('name', 'ulr', "email")
.addBearerAuth({ type: 'http', schema: 'Bearer', bearerFormat: 'Token' } as SecuritySchemeObject, 'Bearer')
.build();
控制器文件
@ApiBearerAuth("Bearer")
@Controller('posts')
export class PostController {
constructor(private readonly postService: PostService) { }
}
Set your token
我目前在我的 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',
})
有了这个,资源管理器可以在 /docs
中访问,这正是我所期望的。但我想知道是否可以向资源管理器添加任何身份验证层,因此只接受某些请求。
我想让这个资源管理器在生产环境中可以访问,但仅限经过身份验证的用户。
提前致谢:)
对于遇到类似挑战的任何人,您可以在 Nestjs 中向您的 Swagger UI 添加身份验证,如下所示。
const options = new DocumentBuilder()
.setTitle('Sample Project API')
.setDescription('This is a sample project to demonstrate auth in Swagger UI')
.setVersion('1.0')
.addTag('Nestjs Swagger UI')
.setContactEmail('your_contact@mail.com')
.addBearerAuth('Authorization', 'header', 'basic')
.setBasePath('api')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('docs', app, document);
所以 .addBearerAuth 需要 3 个参数(密钥名称、位置、身份验证类型)。授权类型可以是 basic
、bearer
或 apikey
更新
根据最近对 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);
更新另外,请在您的控制器功能上使用@ApiBearerAuth()
添加授权。
@Get('/test')
@ApiBearerAuth()
access-token
是 swagger 文档中供参考的名称。您在 header 中的令牌将按如下方式传递:
curl -X GET "http://localhost:3004/test" -H "accept: application/json" -H "Authorization: Bearer test-token"
只需将 .addBearerAuth()
(不带任何参数)添加到您的 swagger 选项中
和@ApiBearerAuth()
到您的控制器方法
const options = new DocumentBuilder()
.setTitle('My App')
.setSchemes('https')
.setDescription('My App API documentation')
.setVersion('1.0')
.addBearerAuth()
.build()
以下示例运行良好
.addBearerAuth({ in: 'header', type: 'http' })
你应该告诉 in
prop
并且由于您覆盖了默认选项,因此您应该传递 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();
addBearerAuth
实施
addBearerAuth(options = {
type: 'http'
}, name = 'bearer') {
this.addSecurity(name, Object.assign({ scheme: 'bearer', bearerFormat: 'JWT' }, options));
return this;
}
这是 APIKEY 不持有者
万一有人到达此 post 并寻找 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();
然后在你的控制器或方法中
@ApiTags('analyzer')
@ApiSecurity('access-key') // this is the name you set in Document builder
@Controller('analyzer')
export class ScreenAnalyzerController {
根据@nestjs/swagger 4.0 版中的 breaking/API 更改进行了更新。
嗨, 花了很多尝试和失败才能做到这一点。 代码中的注释是理解的重要内容。这些名称相互依赖才能发挥作用。
main.ts
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);
然后在您的控制器中执行以下操作(注意@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;
}
希望这可以节省一些人我理解发生了什么的时间。
使用 NestJS 和 Express 通过 HTTP 基本身份验证保护对 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',
})
// ...
有了这个,您将在任何 /docs
路由上收到带有 HTTP 基本身份验证提示的提示。我们也必须明确命名 /docs-json
,以保护生成的 JSON OpenAPI 文件。
您不应将凭据放在 code/repository 中,而应放在 .env
中并通过 ConfigService.
我第一次看到这个解决方案here。
您可以通过添加 addApiKey
或 addBearerAuth
示例来完成此问题的其他答案。
在我这边,我可以添加 OAuth2 身份验证 @nestjs/swagger3** 和@nestjs/swagger4**
在实现上有一些区别For the @nestjs/swagger3**
const options = new DocumentBuilder()
.setTitle('API')
.setDescription('API')
.setVersion('1.0')
.setSchemes('https', 'http')
.addOAuth2('implicit', AUTH_URL, TOKEN_URL)
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup(swaggerPath, app, document, {
swaggerOptions: {
oauth2RedirectUrl: REDIRECT_URL, // after successfully logging
oauth: {
clientId: CLIENT_ID,
},
},
});
addOAuth2 还支持密码、应用程序和访问代码等流程
For the @nestjs/swagger4**
const options = new DocumentBuilder()
.setTitle('API')
.setDescription('API description')
.setVersion(version)
.addServer(host)
.addOAuth2(
{
type: 'oauth2',
flows: {
implicit: {
authorizationUrl: AUTH_URL + `?nonce=${getRandomNumber(9)}`, // nonce parameter is required and can be random, for example nonce=123456789
tokenUrl: TOKEN_URL,
scopes: SCOPES, // { profile: 'profile' }
},
},
},
'Authentication'
)
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup(swaggerPath, app, document, {
swaggerOptions: {
oauth2RedirectUrl: REDIRECT_URL, // after successfully logging
oauth: {
clientId: CLIENT_ID,
},
},
});
对于无法通过上述答案解决的任何人。
这是我添加不记名令牌的方法
const options = new DocumentBuilder()
.setTitle('My API')
.setDescription('My api')
.setVersion('1.0.0')
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
name: 'JWT',
description: 'Enter JWT token',
in: 'header',
},
'token'
)
.build();
添加后不要忘记添加装饰器@ApiBearerAuth('token')
还有一件事要注意,.addBearerAuth({...}, 'token')
方法中的第二个参数需要添加到装饰器中,这样只有您才能在 curl 请求中看到授权。
@Controller('api')
@ApiBearerAuth('token')
你也可以将它留空 @ApiBearerAuth()
并从
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
name: 'JWT',
description: 'Enter JWT token',
in: 'header',
})
NestJS 文档需要改进
根据之前的答案,您可能会看到此错误(如果您想使用 express-basic-auth
模块
Type 'typeof expressBasicAuth' has no call signatures.
Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead
对于这种情况,您可以在 main.ts
中使用.default
import * as basicAuth from 'express-basic-auth';
async function bootstrap() {
app.use(['/docs'], basicAuth.default({
challenge: true,
users: {
[process.env.SWAGGER_USERNAME]: process.env.SWAGGER_PASSWORD,
},
}));
const options = new DocumentBuilder()
.setTitle('api')
.setDescription('API description')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('docs', app, document);
}
在你的 main.ts 文件中添加这个
const config = new DocumentBuilder()
.setTitle('App title')
.setDescription("Api description")
.setVersion('1.0')
.addTag('ApiTag')
.setContact('name', 'ulr', "email")
.addBearerAuth({ type: 'http', schema: 'Bearer', bearerFormat: 'Token' } as SecuritySchemeObject, 'Bearer')
.build();
控制器文件
@ApiBearerAuth("Bearer")
@Controller('posts')
export class PostController {
constructor(private readonly postService: PostService) { }
}
Set your token