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

时间:2018-12-05 07:09:22

标签: aws-lambda aws-api-gateway serverless-framework

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

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

任何人都不知道为什么以及如何使它通过吗?

背景

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

originalUrl: '/dev/endpoint?Origin=MY%20ORIGIN%20HERE',

因此,我可以从查询字符串值中提取原始信息,但是我想知道这是否是在无服务器框架上执行操作的正确方法,还是应该设置一些允许API Gateway通过以下方式发送原始信息的方法?在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

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

app.use((req, res) => {
  console.log('LOG REQUEST', req)
  res.send('interesting')
})

在我的处理程序函数中,我只想获取已发送的原始请求标头。在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',

但是:在POST中,所有其他标头都在那里,但是origin为空白。

1 个答案:

答案 0 :(得分:1)

我对此做了一些挖掘,并遇到了一些认识。

默认情况下,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

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

最后是响应对象

{
    "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
    }
}