当前位置: 首页 > 知识库问答 >
问题:

如何使用 Swagger 3 将自定义中间件添加到表达式-openapi-验证器

金成济
2023-03-14

我有一个使用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密钥,其他endpoint需要调用方在请求头中有API密钥来验证请求。

我知道应该可以使用中间件来验证请求,但是我不知道如何在选择的endpoint上使用带有express-openapi-validator包的定制中间件。

例如:

GET /apikey=不需要api密钥GET /resource=需要api密钥

如何配置?

以下是我的应用程序中的openapi验证程序代码。js看起来像:

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,
      });
    });
  });

共有3个答案

从经略
2023-03-14

我的情况和你类似,使用像这样的OpenAPI/Swagger包限制了我为每个endpoint添加特定中间件的能力,所以我的解决方案是我创建了一个名为@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)
}

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

周伟泽
2023-03-14

您可以简单地传递处理程序数组,而不仅仅是1个函数,就像在 EXPRESS 中一样。因此,在您的代码中,可能就是 x-eov 操作-id 所指的 getUser 函数,将是一个由 2 个函数组成的数组:

const getUsers = [
  apiKeyMiddleware,
  (req, res) => {
    const { 'x-user-id': userId } = req.headers
    res.status(200).json(`Your userId is ${userId}`)
  }
];
弓玉书
2023-03-14

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

首先,我使用的是 4.10.5 版的 express-openapi-验证器,所以上面的代码略有不同。

现在看起来是这样的:

// 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文件中添加了一个< code>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密钥,一个处理程序密钥,然后在我的swagger.yml中有相关的密钥(验证ApiKey和bearerAuth)。这些函数获取请求和范围来检查它们是否有效。这些函数返回一个布尔值,因此true表示中间件允许请求通过,false表示将返回一个403响应。

validateSecurity: {
        handlers: {
          verifyApiKey(req, scopes) {
            return middleware.verifyApiKey(req)
          },
          bearerAuth(req, scopes) {
            return middleware.verifyToken(req)
          }
        }
      },

如果我有任何以上的错误,或者如果解释可以更清楚,请回复。如果你有问题,请在下面发表。

 类似资料:
  • 问题内容: 我有一个带有输入字段和通过添加属性等进行验证设置的表单。但是对于某些领域,我需要做一些额外的验证。我将如何“利用” 控制的验证? 自定义验证可能类似于“如果填写了这3个字段,则此字段是必需的,并且需要以特定方式进行格式化”。 有一个方法,但是看起来不像公共API,所以我宁愿不使用它。创建自定义指令并使用它看起来像另一个选项,但是基本上需要我为每个自定义验证规则创建一个指令,而这是我所不

  • 在中有一个方法,但它看起来不像是一个公共API,所以我宁愿不使用它。创建自定义指令并使用看起来是另一种选择,但基本上需要为每个自定义验证规则创建一个指令,而我不希望这样做。 实际上,在最简单的场景中,将控制器中的某个字段标记为无效(同时保持同步)可能是我完成任务所需要的,但我不知道如何做到这一点。

  • 问题内容: 我仍然很难理解如何将中间件添加到sails.js。我听说过使用policy.js,创建自定义策略,添加到local.js等。所以有人可以告诉我如何将jquery- file-upload-middleware 添加到Sails 应用程序中。提前致谢 问题答案: 在Sails的早期版本中,这将非常困难,因为您无法控制包含自定义中间件的顺序。在v0.10中,这 有点 困难。 注意:以下内容

  • 问题内容: 如何添加自定义CSS文件?以下配置对我不起作用: 结果: 问题答案: 一种简单的方法是将其添加到您的: 然后将文件放入文件夹。

  • 问题内容: 我已经构建了自己的自定义react-bootstrap Popover组件: 该组件的呈现方式如下: 现在,我想向组件中添加自定义道具,例如:我的文字,并使用新道具在弹出框中设置一些内容,例如- 但随后我在浏览器中收到此警告: 警告:标签上的未知道具。从元素中删除这些道具。 现在,我想我可以删除零件并逐个插入所有原始道具,而无需自定义道具,但是这样我就失去了“淡入淡出”效果,这也是处理

  • 问题内容: 我有一个带有开始和结束日期范围的Django模型。我想强制执行验证,以便没有两个记录具有重叠的日期范围。最简单的实现方式是什么,这样我就不必重复编写逻辑了? 例如,我不想在Form 和 a 以及 admin表单中重新实现此逻辑, 并且 模型被重写。 据我所知,Django在全球范围内强制执行这些类型的条件并不容易。 Googling并不是很有帮助,因为“模型验证”通常是指验证特定的模型