在 api 网关前端的无服务器部署 lambda 中获取原始标头的正确方法是什么?

Nic*_*rum 6 aws-lambda aws-api-gateway serverless-framework

我正在使用无服务器框架在 api 网关后面部署一个简单的 lambda(用 node/express 编写)...

GET我可以看到origin标题,但在POST我不能 - 它没有传递到我的 lambda 函数中!

任何人都知道为什么不这样做以及如何让它通过?

背景:

我确实注意到在POST原点中似乎附加到日志中的查询字符串:

originalUrl: '/dev/endpoint?Origin=MY%20ORIGIN%20HERE',
Run Code Online (Sandbox Code Playgroud)

因此,我可以从查询字符串值中提取源,但我想知道这是否是在无服务器框架上执行操作的正确方法,还是应该设置一些内容以允许 API 网关通过POST类似方式发送源它GET呢?为什么这两个动词的行为不同?

我的代码/配置:

serverless.yml 中的函数定义如下所示:

myGetFunction:
  handler: lambda/index.handler
  events:
    - http:
        path: /endpoint
        method: get
        cors: true
myPostFunction:
  handler: lambda/index.handler
  events:
    - http:
        path: /endpoint
        method: post
        cors: true
Run Code Online (Sandbox Code Playgroud)

如果我只是将以下内容放入我的 index.handler 中:

app.use((req, res) => {
  console.log('LOG REQUEST', req)
  res.send('interesting')
})
Run Code Online (Sandbox Code Playgroud)

在我的处理程序函数中,我只想获取发送的原始请求标头。在GET它的方便:CloudWatch的日志显示,它是在头对象中的GET请求提供:

headers: 
  {
    accept: '*/*',
    'accept-encoding': 'gzip, deflate',
    'cache-control': 'no-cache',
    'cloudfront-forwarded-proto': 'https',
    'cloudfront-is-desktop-viewer': 'true',
    'cloudfront-is-mobile-viewer': 'false',
    'cloudfront-is-smarttv-viewer': 'false',
    'cloudfront-is-tablet-viewer': 'false',
    'cloudfront-viewer-country': 'GB',
    host: 'X.execute-api.us-east-1.amazonaws.com',
    origin: 'MY ORIGIN HERE',
Run Code Online (Sandbox Code Playgroud)

但是:在POST所有其他标题中都存在,但是origin是空白的。

小智 6

我对此进行了一些挖掘并得到了一些认识。

默认情况下,API 网关事件中似乎没有传递“origin”标头。(我创建了一个新的无服务器项目,只是回显了 API 网关事件的具体内容。)所以这是来自其他一些来源。我认为它可能是一个自定义域,并进行了测试。没有骰子。

我唯一的另一个猜测是,您在其他层(CloudFront?)后面有这个层,该层正在为您转发这些标头。如果情况确实如此,我建议您查看一下是否可以使其为请求转发这些标头,POST就像为请求转发一样GET

如果以上都不是真的,我唯一的最后一个想法是,某些快速中间件中存在一些魔力。我怀疑情况确实如此。

作为参考,这是我的完整测试serverless.ymlhandler.js以及我在端点中获得的完整未更改的事件对象。

service: so-test

provider:
name: aws
runtime: nodejs8.10

functions:
myGetFunction:
    handler: handler.hello
    events:
    - http:
        path: /endpoint
        method: get
        cors: true
myPostFunction:
    handler: handler.hello
    events:
    - http:
        path: /endpoint
        method: post
        cors: true
Run Code Online (Sandbox Code Playgroud)

和nodejs代码:

'use strict';

module.exports.hello = async (event, context) => {
return {
    statusCode: 200,
    body: JSON.stringify({
    message: 'Go Serverless v1.0! Your function executed successfully!',
    input: event,
    }),
};
};
Run Code Online (Sandbox Code Playgroud)

最后是响应对象

{
    "message": "Go Serverless v1.0! Your function executed successfully!",
    "input": {
        "resource": "/endpoint",
        "path": "/test/endpoint",
        "httpMethod": "GET",
        "headers": {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "en-US,en;q=0.9",
            "CloudFront-Forwarded-Proto": "https",
            "CloudFront-Is-Desktop-Viewer": "true",
            "CloudFront-Is-Mobile-Viewer": "false",
            "CloudFront-Is-SmartTV-Viewer": "false",
            "CloudFront-Is-Tablet-Viewer": "false",
            "CloudFront-Viewer-Country": "US",
            "Host": "so-test.serverless-examples.com",
            "upgrade-insecure-requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
            "Via": "2.0 f92491812e422470607f365e923929b5.cloudfront.net (CloudFront)",
            "X-Amz-Cf-Id": "6AwZPV3uCYxseJIAmsGzhApzRostCiLXwwM3XsbSJP4K8hQx11MSgw==",
            "X-Amzn-Trace-Id": "Root=1-5c086dd9-bce03ab0c216116fa6de9786",
            "X-Forwarded-For": "55.55.55.555, 70.132.32.155",
            "X-Forwarded-Port": "443",
            "X-Forwarded-Proto": "https"
        },
        "multiValueHeaders": {
            "Accept": [
                "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
            ],
            "Accept-Encoding": [
                "gzip, deflate, br"
            ],
            "Accept-Language": [
                "en-US,en;q=0.9"
            ],
            "CloudFront-Forwarded-Proto": [
                "https"
            ],
            "CloudFront-Is-Desktop-Viewer": [
                "true"
            ],
            "CloudFront-Is-Mobile-Viewer": [
                "false"
            ],
            "CloudFront-Is-SmartTV-Viewer": [
                "false"
            ],
            "CloudFront-Is-Tablet-Viewer": [
                "false"
            ],
            "CloudFront-Viewer-Country": [
                "US"
            ],
            "Host": [
                "so-test.serverless-examples.com"
            ],
            "upgrade-insecure-requests": [
                "1"
            ],
            "User-Agent": [
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
            ],
            "Via": [
                "2.0 f92491812e422470607f365e923929b5.cloudfront.net (CloudFront)"
            ],
            "X-Amz-Cf-Id": [
                "6AwZPV3uCYxseJIAmsGzhApzRostCiLXwwM3XsbSJP4K8hQx11MSgw=="
            ],
            "X-Amzn-Trace-Id": [
                "Root=1-5c086dd9-bce03ab0c216116fa6de9786"
            ],
            "X-Forwarded-For": [
                "55.55.55.555, 70.132.32.155"
            ],
            "X-Forwarded-Port": [
                "443"
            ],
            "X-Forwarded-Proto": [
                "https"
            ]
        },
        "queryStringParameters": null,
        "multiValueQueryStringParameters": null,
        "pathParameters": null,
        "stageVariables": null,
        "requestContext": {
            "resourceId": "mftg6x",
            "resourcePath": "/endpoint",
            "httpMethod": "GET",
            "extendedRequestId": "RdYZ7HaxoAMFQYQ=",
            "requestTime": "06/Dec/2018:00:31:21 +0000",
            "path": "/test/endpoint",
            "accountId": "800708648372",
            "protocol": "HTTP/1.1",
            "stage": "dev",
            "domainPrefix": "so-test",
            "requestTimeEpoch": 1544056281163,
            "requestId": "410632a3-f8ee-11e8-a7e2-7d886f93a0e4",
            "identity": {
                "cognitoIdentityPoolId": null,
                "accountId": null,
                "cognitoIdentityId": null,
                "caller": null,
                "sourceIp": "55.55.55.555",
                "accessKey": null,
                "cognitoAuthenticationType": null,
                "cognitoAuthenticationProvider": null,
                "userArn": null,
                "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
                "user": null
            },
            "domainName": "so-test.serverless-examples.com",
            "apiId": "txctij0cnp"
        },
        "body": null,
        "isBase64Encoded": false
    }
}
Run Code Online (Sandbox Code Playgroud)