【问题标题】:Http Request headers not always available in AWS LambdaHttp 请求标头在 AWS Lambda 中并不总是可用
【发布时间】:2020-09-04 14:08:50
【问题描述】:

我通过无服务器框架使用 API Gateway 和 AWS Lambda 来创建 API 端点。 lambda 函数默认部署为 lambda 代理。

当我向我的一个端点发送POST 请求时,我会包含client_version: 1.0.0 等自定义标头。

现在奇怪的事情发生了,当向端点发出请求时,Lambda 函数并不总是获得标头 client_version。这主要发生在将服务部署到 aws 后几分钟,一段时间后 lambda 函数收到标头。但有时它会收到标头,然后在未来的某个时间它不会再次收到标头。

我测试了从我的机器和在线服务向单个端点发出请求,它似乎是完全独立的。

这意味着我的机器 POST 请求可能会发生奇怪的错误,而在线服务 POST 请求成功地设法将标头传递给 lambda 函数,或者同时以其他方式传递。

这让我发疯,因为我根本不知道问题可能是什么,我需要将自定义标头始终发送到我的端点。任何帮助表示赞赏。

无服务器配置

serverless.yml:

custom: ${file(serverless_config/custom.yml):custom}
functions: ${file(serverless_config/functions.yml):functions}
resources: ${file(serverless_config/resources.yml):resources}

service: "${self:custom.WEBSERVICE_NAME}"

provider:
    name: aws
    profile: "${self:custom.CURRENT_PROFILE}"
    stage: "${self:custom.CURRENT_DEPLOY_MODE}"
    region: "${self:custom.AWS_DEPLOY_REGION}"
    runtime: "${self:custom.AWS_LAMBDA_RUNTIME}"
    memorySize: ${self:custom.AWS_LAMBDA_MEMORY_SIZE}
    timeout: "${self:custom.AWS_LAMBDA_TIMEOUT}"
    logRetentionInDays: ${self:custom.AWS_CLOUDWATCH_LOG_TTL}
    environment: ${file(serverless_config/environment.yml):environment}

functions.yml

functions:
    Account-Create:
        role: DefaultLambdaIAMRole
        handler: src/v1/Account/Create/Email/main.main
        events:
            - http:
                path: v${self:custom.CURRENT_API_VERSION}/account/create-email
                method: POST

custom.yml:

custom:

    WEBSERVICE_NAME: account-service
    WEBSERVICE_ENDPOINT: "api.accountservice.testing.galaxgate.com"

    DEFAULT_DEPLOY_MODE: dev
    stage: "${opt:stage, self:custom.DEFAULT_DEPLOY_MODE}"
    CURRENT_DEPLOY_MODE: "${self:custom.stage}"
    CURRENT_PROFILE: galaxfinity
    CURRENT_API_VERSION: "1"

    WEBSERVICE_PREFIX: "${self:custom.WEBSERVICE_NAME}-${self:custom.CURRENT_DEPLOY_MODE}-"


    AWS_ACCOUNT_ID: "XXXXXXXXX"
    AWS_DEPLOY_REGION: eu-central-1 # dep: _config.js
    AWS_LAMBDA_RUNTIME: nodejs12.x
    AWS_LAMBDA_TIMEOUT: 30
    AWS_LAMBDA_MEMORY_SIZE: 512

    IAM_LAMBDA_POLICY_NAME: "${self:custom.WEBSERVICE_PREFIX}policy-lambda"
    IAM_LAMBDA_ROLE_NAME: "${self:custom.WEBSERVICE_PREFIX}role-lambda"

    AWS_CLOUDWATCH_LOG_TTL: 180 # in days


    DB_TABLE_DELETION_POLICY_VALUES:
        dev: Delete
        prod: Retain
    DB_TABLE_DELETION_POLICY: ${self:custom.DB_TABLE_DELETION_POLICY_VALUES.${self:custom.stage}}

    S3_BUCKET_DELETION_POLICY_VALUES:
        dev: Delete
        prod: Retain
    S3_BUCKET_DELETION_POLICY: ${self:custom.S3_BUCKET_DELETION_POLICY_VALUES.${self:custom.stage}}

    customDomain:
        endpointType: 'regional'
        securityPolicy: tls_1_2
        domainName: '${self:custom.WEBSERVICE_ENDPOINT}'
        certificateName: '${self:custom.WEBSERVICE_ENDPOINT}'
        basePath: '${self:custom.CURRENT_DEPLOY_MODE}'
        stage: ${self:custom.CURRENT_DEPLOY_MODE}
        createRoute53Record: true

一些图片

相同的请求导致不同的结果。

Postman headers

Sometimes without header

Most of the time with header

更新 1 我能够直接从 API Gateway 输入获取日志。似乎 API Gateway 甚至没有收到自定义标头。仍然无法相信邮递员会造成麻烦。

Method request headers: {Accept=*/*, Cache-Control=no-cache, User-Agent=PostmanRuntime/7.24.1, X-Forwarded-Proto=https, X-Forwarded-For=5.147.136.132, Host=api.accountservice.testing.galaxgate.com, Postman-Token=9236b95a-3cef-4e04-a188-38e996122811, Accept-Encoding=gzip, deflate, br, X-Forwarded-Port=443, X-Amzn-Trace-Id=Root=1-5ec30f6a-6e719a6a7cc4e1c12e54c030, Content-Type=text/plain}

更新 2

在这里你可以看到这一切的怪异之处。我使用 reqbin.com 发送两个请求,一个来自美国服务器,一个来自 DE 服务器。服务器应以PAYLOAD_INVALID 响应。但是当没有设置标题字段client_version 时,它会以CLIENT_VERSION_MISSING 响应。

从什么时候开始,标题字段在通过 Internet 发送时神秘地消失了?

最终大更新

我找到了解决方案:事实证明,将自定义标头 client_version 更改为 X-Client-Version 解决了问题,并且始终收到标头。我不知道为什么这样的事情会影响 API Gateway 的功能,但我对工作解决方案很好。

【问题讨论】:

  • 能否像使用 Postman 一样在本地重现错误?
  • 是的,我使用 Postman 发出请求,当我将服务部署到 aws 时,有 33% 的机会出现“错误”。然后它通常就像我对 Postman 所做的前 10-30 个请求一样,最终没有将 client_version 标头传递给 lambda 函数,并且在一段时间后它可以工作(即使我没有改变任何东西)
  • 再过一段时间,lambda 函数可能会再次开始不接收自定义标头(对服务没有任何更改)
  • 你能发布你的无服务器配置吗?

标签: amazon-web-services aws-lambda http-headers serverless-framework api-gateway


【解决方案1】:

您需要在 cors 上设置自定义标头 https://www.serverless.com/framework/docs/providers/aws/events/apigateway#enabling-cors

例如:

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
          cors:
            origin: '*'
            headers:
              - Content-Type
              - X-Amz-Date
              - Authorization
              - client_version
            allowCredentials: false

【讨论】:

  • 我也这样做了,但没有运气。但我找到了解决方案:事实证明,将自定义标头 client_version 更改为 X-Client-Version 可以解决问题并且始终收到标头。我不知道为什么这样的事情会影响 API Gateway 的功能,但我对工作解决方案很好。
  • @iOSonntag,同样的问题,使用了 mobile_version 之类的标头,更改为 X-Mobile-Version,然后繁荣......它的工作))感谢您的解决方案
猜你喜欢
  • 2015-10-01
  • 2015-10-27
  • 2020-01-22
  • 2015-05-16
  • 1970-01-01
  • 2018-05-04
  • 2019-06-14
  • 1970-01-01
  • 2018-12-18
相关资源
最近更新 更多