I'm using API Gateway's Proxy integration to call a Lambda. The output format specification is this follow JSON format:
{
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
In one response I wish to set two cookies (two different auth cookies) but JSON doesn't allow having two identical keys in the headers object (OK, technically the spec does but most libraries do not).
RFC 7230 notes that Set-Cookie should be handled specially but I can't see how I can send multiple Set-Cookie values through API gateway.
Does anyone know whether this is possible?
Having experimented with this I've concluded that it isn't currently possible (will update if I hear back otherwise from AWS support).
I've tried sending the following manually curated JSON as a response:
{
"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"
}
}
The cookies that API gateway returns in response to a CURL request are:
< 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
As you can see the first Set-Cookie is dropped on the floor.
Ideally the JSON format for the headers in the JSON output format should be something like:
{
"statusCode": httpStatusCode,
"headers": [
{ "headerName": "headerValue" },
...
],
"body": "..."
}
As Mark B pointed out, you can/should achieve this by setting multiple cookie name/value pairs in a single Set-Cookie header. The browser should interpret this correctly.
Cookie: a=1; b=2
Edit: as pointed out by OP, there are use cases that require multiple instances of the header. We've added it our backlog along with supporting multiple header names on incoming requests.
Use multiValueHeaders:
response.multiValueHeaders = {
"Set-Cookie": [
'cookie1=value1',
'cookie1=value1'
]
}
or:
{
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"multiValueHeaders": { "headerName": ["headerValue", "headerValue2",...], ... },
"body": "..."
}
As answered, to date, API Gateway will drop identical keys, only setting one of the cookies.
However, a workaround exists. You can change the casing of the string 'Set-Cookie' so the keys are not unique. For example, you could use the keys set-cookie, Set-cookie, sEt-cookie, and the headers will be preserved and 3 different cookies would be set.
Because the RFC standard makes headers case-insensitive this should work with all RFC-compliant clients.
So, you could rewrite your set-cookie headers, permuting all the possible casings of "Set-Cookie" to get around this.
This technique (hack) is employed by Zappa, a popular serverless framework written in Python.
Couple of years late, but I just required to implement something like this and this is how I was able to make it work:
...
//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;
...
Each array item will be processed independently, so you can add as many cookies to the array with different settings.
i.e.
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>");
来源:https://stackoverflow.com/questions/39769222/how-can-i-send-multiple-set-cookie-headers-from-api-gateway-using-a-proxied-lamb