如何解决如何使用Swagger 3将自定义中间件添加到express-openapi-validator
我有一个使用express-openapi-validator的Node应用程序,该应用程序使用一个带有请求和响应验证的api规范文件(这是一个.yml文件)。 express-openapi-validator软件包将请求路由到处理程序文件(在规范中定义)。这是其中一个处理程序的外观:
function getUsers(req,res) {
const { 'x-user-id': userId } = req.headers
res.status(200).json(`Your userId is ${userId}`)
}
我有一个API密钥功能,用户可以获取一个新的API密钥,其他需要调用者在请求标头中具有API密钥以验证请求的端点。
我知道应该可以使用中间件来验证请求,但是我不知道如何在选定的端点上将自定义中间件与express-openapi-validator包一起使用。
例如:
GET / apikey =不需要api密钥 GET / resource =需要api键
我该如何配置?
这是我的app.js中的openapi验证程序代码如下:
new OpenApiValidator({
apiSpec,validateResponses: true,operationHandlers: path.join(__dirname,'./handlers'),})
.install(app)
.then(() => {
app.use((err,_,res) => {
res.status(err.status || 500).json({
message: err.message,errors: err.errors,});
});
});
解决方法
实际上我自己最终找到了解决方案。
首先,我使用的是 4.10.5
的 express-openapi-validator
版本,因此上面的代码略有不同。
这是现在的样子:
// index.js
app.use(
OpenApiValidator.middleware({
apiSpec,validateResponses: true,operationHandlers: path.join(__dirname,'./handlers'),validateSecurity: {
handlers: {
verifyApiKey(req,scopes) {
return middleware.verifyApiKey(req)
},bearerAuth(req,scopes) {
return middleware.verifyToken(req)
}
}
},}),);
app.use((err,req,res,next) => {
res.status(err.status || 500).json({
message: err.message,errors: err.errors,});
我最终在路由中使用中间件的方式如下:
我在我的 swagger.yml 文件中添加了一个 securitySchemes
部分,如下所示:
components:
securitySchemes:
verifyApiKey:
type: apiKey
in: header
name: x-api-key
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
这里有更多关于它的信息:https://swagger.io/docs/specification/authentication/
在需要中间件的每条路由上,我都添加了一个安全部分,如下所示:
/team:
post:
security:
- bearerAuth: []
description: Create a new team
operationId: createTeam
x-eov-operation-id: createTeam
x-eov-operation-handler: team
正如您在我上面的代码(在 index.js 文件中)中看到的,我有一个 validateSecurity
键,带有一个 handlers
键,该键然后具有在我的swagger.yml(verifyApiKey 和bearerAuth)。这些函数获取请求和范围以检查它们是否有效。这些函数返回一个布尔值,因此 true
表示中间件允许请求通过,而 false
表示将返回 403
响应。
validateSecurity: {
handlers: {
verifyApiKey(req,
如果我有以上任何错误,或者解释可以更清楚,请回复。如果您有任何问题,请在下方留言。
,您可以简单地传递处理程序数组,而不是像 express 那样只传递 1 个函数。
因此,在您的代码中,可能是 x-eov-operation-id 所指的 getUsers
函数将是一个包含 2 个函数的数组:
const getUsers = [
apiKeyMiddleware,(req,res) => {
const { 'x-user-id': userId } = req.headers
res.status(200).json(`Your userId is ${userId}`)
}
];
,
我和你的情况类似,使用 OpenAPI/Swagger 包限制了我为每个端点添加特定中间件的能力,所以我的解决方案是我创建了一个名为 @zishone/chaindler 的 npm 模块。
你可以这样使用它:
const { Chain } = require('@zishone/chaindler');
function getUsers(req,res) {
const { 'x-user-id': userId } = req.headers
res.status(200).json(`Your userId is ${userId}`)
}
function postUsers(req,res) {
// ...
}
function mw1(req,next) {
next()
}
function mw2(req,next) {
next()
}
module.exports = {
getUsers: new Chain(mw1,mw2).handle(getUsers),postUsers: new Chain(mw1).handle(postUsers)
}
基本上它只是链接中间件,然后一个一个调用它们,最后调用处理程序/控制器。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。