【问题标题】:How to add custom middleware to express-openapi-validator using Swagger 3如何使用 Swagger 3 将自定义中间件添加到 express-openapi-validator
【发布时间】:2020-11-07 19:08:59
【问题描述】:

我有一个使用 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,
      });
    });
  });

【问题讨论】:

标签: node.js swagger-3.0 express-openapi-validator


【解决方案1】:

实际上,我自己最终找到了解决方案。

首先,我使用的是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, scopes) {
            return middleware.verifyApiKey(req)
          },
          bearerAuth(req, scopes) {
            return middleware.verifyToken(req)
          }
        }
      },

如果我有任何上述错误,或者解释可以更清楚,请回复。如果您有任何问题,请在下方发布。

【讨论】:

    【解决方案2】:

    您可以简单地传递处理程序数组,而不是像 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}`)
      }
    ];
    

    【讨论】:

      【解决方案3】:

      我的情况和你类似,使用 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, res, next) {
        next()
      }
      
      function mw2(req, res, next) {
        next()
      }
      
      module.exports = {
        getUsers: new Chain(mw1, mw2).handle(getUsers),
        postUsers: new Chain(mw1).handle(postUsers)
      }
      

      基本上它只是链接中间件,然后一个接一个地调用它们,然后最后调用处理程序/控制器。

      【讨论】:

      • 谢谢,实际上我找到了一种不使用任何软件包的方法!
      猜你喜欢
      • 2021-03-13
      • 2021-02-25
      • 2014-03-23
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      相关资源
      最近更新 更多