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

时间:2016-09-29 11:37:21

标签: json amazon-web-services cookies aws-lambda aws-api-gateway

我使用API​​网关的代理集成来调用Lambda。输出格式规范遵循JSON格式:

{
  "statusCode": httpStatusCode,
  "headers": { "headerName": "headerValue", ... },
  "body": "..."
}

在一个回复中,我希望设置两个cookie(两个不同的auth cookie),但JSON不允许在headers对象中使用两个相同的键(好的,从技术上来说,规范确实如此,但是大多数库都没有)。

RFC 7230注意到应该专门处理Set-Cookie,但我不知道如何通过API网关发送多个Set-Cookie值。

有谁知道这是否可行?

5 个答案:

答案 0 :(得分:4)

经过实验,我得出的结论是,目前无法实现(如果我从AWS支持部门收到其他回复,将会更新)。

我尝试发送以下手动策划的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"
  }
}

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

正如您所看到的那样,第一个Set-Cookie被丢弃在地板上。

理想情况下,JSON输出格式的标头的JSON格式应为:

{
  "statusCode": httpStatusCode,
  "headers": [
    { "headerName": "headerValue" },
    ...
  ],
  "body": "..."
}

答案 1 :(得分:3)

正如Mark B指出的那样,您可以/应该通过在单个Set-Cookie标头中设置多个cookie名称/值对来实现此目的。浏览器应正确解释这一点。

Cookie: a=1; b=2

编辑:正如OP指出的那样,有些用例需要多个头部实例。我们已经添加了我们的待办事项以及在传入请求中支持多个标题名称。

答案 2 :(得分:2)

回答,到目前为止,API Gateway会丢弃相同的密钥,只设置其中一个cookie。

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

因为RFC标准使标头case-insensitive与所有符合RFC的客户端一起使用。

因此,您可以重写set-cookie标头permuting all the possible casings of "Set-Cookie"来解决此问题。

这种技术(黑客)是employed by Zappa,这是一种用Python编写的流行的无服务器框架。

答案 3 :(得分:1)

使用multiValueHeaders:

response.multiValueHeaders = {
  "Set-Cookie": [
    'cookie1=value1',
    'cookie1=value1'
  ]
}

或:

{
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2",...], ... },
    "body": "..."
}

https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format

答案 4 :(得分:0)

夫妇晚了,但是我只需要实现这样的东西,这就是我使它起作用的方式:

...

//15 minutes
var expirationTime = new Date(new Date().getTime() + 15 * 60 * 1000);
//30 minutes
var expirationTime2 = new Date(new Date().getTime() + 30 * 60 * 1000);

var response = {};

var cookies = [];
cookies.push("testCookie={'keyX':'valx', 'keyy':'valy'}; Expires=" + expirationTime + ";");
cookies.push("testCookie2={'key1':'val1', 'key2':'val2'}; Expires=" + expirationTime2 + ";");

response.headers["Set-Cookie"] =  cookies;

...

每个数组项将被独立处理,因此您可以使用不同的设置将尽可能多的cookie添加到数组中。

cookies.push("testCookie3={'key1':'val1', 'key2':'val2'}; Expires=" + expirationTime2 + "; Max-Age=...");

cookies.push("testCookie4={'key1':'val1', 'key2':'val2'}; Expires=" + expirationTime2 + "; Domain=<domain-value>; Path=<path-value>");