API Gateway 结合 Lambda 集成和 CloudFront 忽略了多个 Set-Cookie 标头

Posted

技术标签:

【中文标题】API Gateway 结合 Lambda 集成和 CloudFront 忽略了多个 Set-Cookie 标头【英文标题】:Multiple Set-Cookie headers ignored by API Gateway in combination with Lambda integration and CloudFront 【发布时间】:2021-05-22 20:43:14 【问题描述】:

我的设置如下所示:

|––––––––––––|                  |–––––––––––––|     |–––––––––––––––––|
|            |  <- origin 1 ->  | API Gateway | <-> | Lambda function |
|            |                  |–––––––––––––|     |–––––––––––––––––|
| CloudFront |  
|            |                  |–––––––––––––|
|            |  <- origin 2 ->  |  S3 bucket  |
|––––––––––––|                  |–––––––––––––|

我需要在 API 网关前使用 CloudFront 来获得自动 http->https 重定向。 我正在使用带有 CloudFront 的自定义 login.example.com 子域。 API Gateway 生成的 URL 是 CloudFront 分发的来源 1。

这一切都按预期工作。

我什至可以从 lambda 函数返回一个 Set-Cookie 标头,它会一直传递到浏览器。


  "statusCode": 302,
  "body": "",
  "headers": 
    "location": "/test",
    "surrogate-control": "no-store",
    "cache-control": "no-store, no-cache, must-revalidate, proxy-revalidate",
    "pragma": "no-cache",
    "expires": "0",
    "content-length": "0",
    "date": "Fri, 19 Feb 2021 17:25:56 GMT",
    "connection": "keep-alive",
    "set-cookie": "cookie1=68abcdbefbef7d84c26e68; Max-Age=2592000; Domain=example.com; Path=/; HttpOnly; Secure; SameSite=Strict"
  ,
  "isBase64Encoded": false

添加另一个不起作用 - 正如您查看文档时所预期的那样:

https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#apigateway-multivalue-headers-and-parameters https://aws.amazon.com/blogs/compute/support-for-multi-value-parameters-in-amazon-api-gateway/

  "statusCode": 302,
  "headers": 
    "location": "/test",
    "set-cookie": [
      "cookie1=68abcdbefbef7d84c26e68; Max-Age=2592000; Domain=example.com; Path=/; HttpOnly; Secure; SameSite=Strict",
      "cookie2-login=; Max-Age=0; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; Secure"
    ],
    "surrogate-control": "no-store",
    "cache-control": "no-store, no-cache, must-revalidate, proxy-revalidate",
    "pragma": "no-cache",
    "expires": "0",
    "content-length": "0"
  

这两个都将被忽略/删除。

但即使我使用 multiValueHeaders 对象返回多个类似这样的对象:


  "statusCode": 302,
  "body": "",
  "headers": 
    "location": "/test",
    "surrogate-control": "no-store",
    "cache-control": "no-store, no-cache, must-revalidate, proxy-revalidate",
    "pragma": "no-cache",
    "expires": "0",
    "content-length": "0",
    "date": "Fri, 19 Feb 2021 17:25:56 GMT",
    "connection": "keep-alive"
  ,
  "isBase64Encoded": false,
  "multiValueHeaders": 
    "Set-Cookie": [
      "cookie1=68abcdbefbef7d84c26e68; Max-Age=2592000; Domain=example.com; Path=/; HttpOnly; Secure; SameSite=Strict",
      "cookie2-login=; Max-Age=0; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; Secure"
    ]
  

API 网关从传递给 CloudFront 的响应中删除/忽略它们。

我做错了什么? 使用multiValueHeaders 时是否必须在 API 网关中映射某些内容? 正常 headers['set-cookie'] 会自动传递,但 multiValueHeaders 不会? 附加属性有问题吗? 我试图为根域而不是 login.example.com 域设置 cookie 是否有问题?

【问题讨论】:

【参考方案1】:

终于自己找到了答案:

新的有效载荷格式(2.0)不支持multiValueHeaders

为 HTTP API 使用 AWS Lambda 代理集成

[...] 格式 2.0 没有 multiValueHeaders 或 multiValueQueryStringParameters 字段。重复的标题与逗号组合并包含在标题字段中。重复的查询字符串用逗号组合并包含在 queryStringParameters 字段中。 [...]

https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html

所以我将set-cookie 标头改写为不同的拼写:

Set-cookie
sEt-cookie
seT-cookie

这是在出现 multiValueHeaders 之前您必须这样做的方式 - 但它似乎仍然是您使用新有效负载格式的唯一方式:(

【讨论】:

嘿 Philipp,我想你想知道可以在响应中设置一个 cookies 数组。效果很好!【参考方案2】:

不确定 Philipp 是如何错过这一点的,因为它在他引用的同一页上:

要自定义响应,您的 Lambda 函数应返回具有以下格式的响应。


    "cookies" : ["cookie1", "cookie2"],
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers":  "headername": "headervalue", ... ,
    "body": "Hello from Lambda!"

所以只需返回cookies: ['name=value', 'name=value']

来源:https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.v2

【讨论】:

肯定会检查一下...谢谢 是的,这对我很有效。谢谢!

以上是关于API Gateway 结合 Lambda 集成和 CloudFront 忽略了多个 Set-Cookie 标头的主要内容,如果未能解决你的问题,请参考以下文章

API Gateway Lambda 端点代理与非代理集成

创建接口调用--lambda与api_gateway结合

如何集成 API Gateway 调用带参数的 Lambda 函数?

API Gateway 方法与 lambda 函数集成,但 lambda 函数声称它没有触发器

AWS API Gateway 集成请求 Http 标头未传递给 lambda

使用 Rest API Gateway lambda 集成 CORS 问题进行放大