【问题标题】:AWS Lambda: how to have multiple handlers for same path?AWS Lambda:如何为同一路径设置多个处理程序?
【发布时间】:2021-01-18 13:02:59
【问题描述】:

我有一个带有 serverless.yml 配置的简单 lambda 函数设置。我想要做的是有一个额外的 lambda 函数,它将为任何已部署的 lambda 函数的 OPTIONS 方法调用。例如,如果使用 OPTIONS 调用 /login,我希望选项处理程序来处理执行。如果 /login 使用 GET 调用,我希望实际的登录处理程序来处理执行。所有其他处理函数也一样。

Serverless.yml

functions:
  login:
    handler: handler.login
    events:
      - http:
          path: login
          method: get
  stats:
    handler: handler.Stats
    events:
      - http:
          path: patientset/{id}/stats
          method: get
  options:
    handler: handler.options
    events:
      - http:
          path: '/' //Need something global like this
          method: options

Handler.js

module.exports.options = (event) => {
  const headers = setHeaders(event);  
  return {
    statusCode: 200,
    headers,
    body: JSON.stringify({})
  }
}

//Code updated in edit
  login:
    handler: handler.login
    events:
      - http:
          path: login
          method: get
          cors:
            origin: 'https://d2mo71maq8qx66.cloudfront.net'
            headers: ${self:custom.ALLOWED-HEADERS}
            allowCredentials: true

【问题讨论】:

    标签: amazon-web-services aws-lambda aws-api-gateway


    【解决方案1】:

    如果我对您的理解正确,那么您必须在 Lambda 函数的代码中组合处理程序函数并处理 GETOPTIONS 之间的区别。目前,您的代码无法正常工作,因为您正在创建三个不同的 Lambda 函数和三个不同的 REST API(其中一个 REST API 与一个 Lambda 函数集成)。这是一个问题,因为每个 REST API 都有不同的端点 url。所以你有http://api-A.../loginhttp://api-B.../patientset/{id}/statshttp://api-C.../ 作为你的端点。为了使用不同的 HTTP 方法(例如 GETOPTIONS)调用一个端点,您需要像这样定义它:

    functions:
      login:
        handler: handler.myHandler
        events:
          - http:
              path: '/login'
              method: get
          - http:
              path: '/login'
              method: 'options'
    

    这将产生一个类似http://api-X.../login 的端点,您可以使用GETOPTIONS 调用它。当您在myHandler 函数中接收到事件时,您需要决定事件对象的httpMethod 参数要执行哪个代码。

    但是,这对您来说似乎还不够,因为您希望为任何部署的 Lambda 函数提供此功能。不幸的是,我不知道为每个部署的 Lambda 函数自动执行此操作的方法。据我所知,您需要将上述options 事件显式添加到您在 Lambda 函数中拥有的每个端点/Lambda 函数,并适当地调整您的处理程序函数。

    除此之外,您不需要为每个路径编写选项事件。您也可以将{proxy+} 用于选项事件。例如:

    events:
      - http:
          method: 'options'
          path: '/{proxy+}'
    

    关于此主题的附注:如果您执行所有这些操作是因为您想返回一些 CORS 标头,那么您应该考虑改用 cors option。这通常会减少您必须编写的配置和代码量。

    【讨论】:

    • 嗨。实际上,我遇到的问题主要与仅允许访问控制允许来源中的单个域有关。我想被 cors 协议自动拒绝的任何其他域。这样做会为 api-gateway 中具有“模拟”集成类型的处理程序创建一个选项路由,它仍然允许访问我正在努力解决的任何域。 (代码在编辑中更新)。
    • 您是否尝试通过将origin 配置中的origin 属性设置为例如限制域你的域名?这应该可以解决问题。所以不要写origin: '*',而是写origin: 'http://example.org'。这也记录在Serverless cors option documentation
    • 是的,它的配置完全一样,请检查编辑代码中的结束位。其他来源,如 localhost:3000 和 postman 仍然能够访问 api。我还返回了处理程序中的标题。
    • 不确定你的本地主机的事情(我不知道你的设置),但 Postman 或类似的开发工具通常不关心 CORS。这是浏览器主要实现的规则。另请参阅有关它的 SO 线程:stackoverflow.com/questions/36250615/cors-with-postman(互联网上还有其他有关它的网站/博客文章)那么,您如何称呼您的端点?使用 Postman 时是否包含 Origin 和其他标题?如果您从您允许的域拨打电话,它是否有效?
    • 适用于我允许的域,但也适用于我不允许的其他域。我不确定 api-gateway 'mock' 集成类型的具体行为是什么以及它是如何工作的。
    猜你喜欢
    • 2023-01-02
    • 1970-01-01
    • 2021-06-16
    • 2018-11-14
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多