目標
nestjs經常需要設置一些鑒權(登錄后)才能訪問的接口,但是生成的swagger文檔可以發起接口請求,文檔發起的請求默認是不攜帶登錄token的,所以需要移除swagger文檔發起請求的守衛攔截。
nestjs守衛攔截設置見另一篇博客?nestjs守衛/全局守衛校驗jwt-CSDN博客
方案一
關閉swagger文檔請求守衛攔截
global.guard.ts
import { Injectable, NestInterceptor, ExecutionContext, HttpException, HttpStatus } from '@nestjs/common';@Injectable()
export class GlobalGuard implements NestInterceptor {intercept(context: ExecutionContext, next): Observable<any> {const request = context.switchToHttp().getRequest();// 判斷是否是swagger文檔訪問,如果請求頭referer包含/api-docs,則認為是swagger文檔訪問// 文檔前綴在main.ts設置,本項目文檔前綴設置的api-docsconst apiDocAccess = request.headers['referer'].indexOf('/api-docs') > -1;if (!apiDocAccess) {// 非文檔訪問、需要鑒權才能訪問的接口,執行鑒權邏輯// ...}// 其他場景直接放行return next.handle();}
}
方案二
swagger文檔添加鑒權請求頭信息
接口添加 jwt 鑒權后,接口文檔調用接口請求頭沒有添加 authorization,請求會返回403。為此,需要給文檔需要鑒權的接口請求頭也添加?authorization
main.ts 配置 BearerAuth 校驗
const config = new DocumentBuilder().setTitle('接口文檔').setDescription('接口文檔描述').setVersion('1.0').addBearerAuth() // 注意此處:文檔添加BearerAuth.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document); // 文檔前綴設為 api-docs
在需要鑒權的接口添加?@ApiBearerAuth() 裝飾器
import { ApiBearerAuth } from '@nestjs/swagger';@Controller('api')
@ApiBearerAuth() // 在此處添加,表示/api/的接口請求頭全都需要添加authorization
export class ApiController {@Get('getUserInfo')@UseGuards(AuthGuard)@ApiBearerAuth() // 在此處添加,表示當前接口請求頭需要添加authorizationgetUserInfo(): any {return this.apiService.getUserInfo();}
}
使用
先調用登錄接口獲取到 jwt_token
注意:可以設置默認請求參數,參數用一個swagger測試賬號,就不用每次調用再改參數了。設置方法如下:
class LoginDto {@ApiProperty({description: '用戶名', default: 'swagger-test'})name: string@ApiProperty({description: '密碼', default: '123456'})password: string
}
點擊文檔頂部Authorize按鈕
輸入獲取到的 jwt_token,并點擊Authorize,然后關閉彈窗
再調用需要鑒權的接口,就可以鑒權通過了
注意:請求頭的 Authorization?參數會在最前面添加 Bearer 字符,可以在守衛中將此字符移除
this.jwtService.verify(token.replace('Bearer ', ''))