如何使用代理的Lambda从API网关发送多个Set-Cookie标头

sih*_*hil 6 cookies json amazon-web-services aws-lambda aws-api-gateway

我正在使用API​​ Gateway的代理集成来调用Lambda.输出格式规范遵循JSON格式:

{
  "statusCode": httpStatusCode,
  "headers": { "headerName": "headerValue", ... },
  "body": "..."
}
Run Code Online (Sandbox Code Playgroud)

在一个响应中,我希望设置两个cookie(两个不同的auth cookie),但JSON不允许在headers对象中具有两个相同的键(好的,技术上规范,但大多数库没有).

RFC 7230指出应该专门处理Set-Cookie,但我看不出如何通过API网关发送多个Set-Cookie值.

有谁知道这是否可能?

sih*_*hil 17

截至 2018 年 11 月,可以multiValueHeaders在响应中使用该字段而不是headers(请参阅公告)。

作为一个例子,而不是:

{
  "statusCode": 200,
  "body": "testing multiple set-cookie headers",
  "headers": {
    "X-Test-Header": "baking experiment",
    "Set-Cookie": "cookie1=chocolate-chip",
    "Set-Cookie": "cookie2=oatmeal",
    "Content-Type": "text/plain"
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以回复:

{
  "statusCode": 200,
  "body": "testing multiple set-cookie headers",
  "multiValueHeaders": {
    "X-Test-Header": ["baking experiment"],
    "Set-Cookie": ["cookie1=chocolate-chip", "cookie2=oatmeal"],
    "Content-Type": ["text/plain"]
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以混合使用headersmultiValueHeaders

{
  "statusCode": 200,
  "body": "testing multiple set-cookie headers",
  "headers": {
    "X-Test-Header": "baking experiment",
    "Content-Type": "text/plain"
  },
  "multiValueHeaders": {
    "Set-Cookie": ["cookie1=chocolate-chip", "cookie2=oatmeal"]
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,在两者中使用相同的标头将意味着下面的值headers被删除。

有关更多详细信息,请参阅文档

仅使用标头字段(2018 年 11 月之前可用)时,我尝试发送以下手动策划的 JSON 作为响应:

{
  "statusCode": 200,
  "body": "testing multiple set-cookie headers",
  "headers": {
    "X-Test-Header": "baking experiment",
    "Set-Cookie": "cookie1=chocolate-chip",
    "Set-Cookie": "cookie2=oatmeal",
    "Content-Type": "text/plain"
  }
}
Run Code Online (Sandbox Code Playgroud)

API 网关响应 CURL 请求返​​回的 cookie 是:

< Content-Type: text/plain
< Content-Length: 35
< Connection: keep-alive
< Date: Thu, 29 Sep 2016 11:22:09 GMT
< Set-Cookie: cookie2=oatmeal
< X-Test-Header: baking experiment
< X-Cache: Miss from cloudfront
Run Code Online (Sandbox Code Playgroud)

如您所见,第一个Set-Cookie掉在地板上。


Sam*_*uel 11

请注意,在 09/2022 中,AWS Api Gateway 默认使用新的有效负载格式(版本 2.0),该格式不再识别multiValueHeaders所有热门答案(包括已接受的答案)提出的建议。我只是花了 40 分钟试图找出为什么它不返回我的 cookie:)。

来自 AWS 文档:

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

格式 2.0 包含一个新的 cookies 字段。请求中的所有 cookie 标头均以逗号组合并添加到 cookies 字段。在对客户端的响应中,每个 cookie 都成为一个 set-cookie 标头。

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

所以现在实际的解决方案应该是:

    return {
      statusCode: 302,
      headers: {
        Location: location,
      },
      cookies: [
         "cookie1=value1;",
         "cookie2=value2;"
      ]
    };
Run Code Online (Sandbox Code Playgroud)


syt*_*ech 8

正如所回答的,迄今为止,API Gateway 将删除相同的密钥,仅设置其中一个 cookie。

但是,存在一种解决方法。您可以更改字符串的大小写'Set-Cookie',使键不唯一。例如,您可以使用键set-cookieSet-cookiesEt-cookie,并且标头将被保留,并且将设置 3 个不同的 cookie。

由于 RFC 标准使标头不区分大小写,因此这应该适用于所有符合 RFC 的客户端。

因此,您可以重写 set-cookie 标头,排列“Set-Cookie”所有可能的大小写来解决此问题。

Zappa 采用了这种技术(hack),Zappa 是一种用 Python 编写的流行无服务器框架。

  • 刚刚看到这个,显然现在已经正确修复了,但无论谁认为这个黑客攻击都值得一个独角兽。杰出的。感谢您让我注意到@sytech (2认同)