![](/img/trans.png)
[英]How to send JSON body from API Gateway without using Lambda in CDK
[英]How can I send multiple Set-Cookie headers from API Gateway using a proxied Lambda
我正在使用 API 网关的代理集成来调用 Lambda。 output 格式规范遵循 JSON 格式:
{
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
在一个响应中,我希望设置两个 cookies (两个不同的身份验证 cookie),但 JSON 不允许在headers
object 中有两个相同的键(好吧,从技术上讲,大多数库都没有)。
RFC 7230指出 Set-Cookie 应特别处理,但我看不出如何通过 API 网关发送多个 Set-Cookie 值。
有谁知道这是否可能?
截至 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"
}
}
您可以回复:
{
"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"]
}
}
请注意,您可以混合使用headers
和multiValueHeaders
:
{
"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"]
}
}
但是,在两者中使用相同的标题将意味着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"
}
}
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
掉在了地板上。
正如 Mark B 指出的那样,您可以/应该通过在单个 Set-Cookie 标头中设置多个 cookie 名称/值对来实现这一点。 浏览器应该正确解释这一点。
Cookie: a=1; b=2
编辑:正如 OP 所指出的,有些用例需要标头的多个实例。 我们已将其添加到我们的待办事项中,并支持传入请求的多个标头名称。
使用 multiValueHeaders:
response.multiValueHeaders = {
"Set-Cookie": [
'cookie1=value1',
'cookie1=value1'
]
}
或:
{
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"multiValueHeaders": { "headerName": ["headerValue", "headerValue2",...], ... },
"body": "..."
}
正如回答的那样,到目前为止,API Gateway 将删除相同的密钥,只设置其中一个 cookie。
但是,存在一种解决方法。 您可以更改字符串'Set-Cookie'
的大小写,因此键不是唯一的。 例如,您可以使用键set-cookie
、 Set-cookie
、 sEt-cookie
,并且将保留标头并设置 3 个不同的 cookie。
因为 RFC 标准使标头不区分大小写,所以这应该适用于所有符合 RFC 的客户端。
因此,您可以重写 set-cookie 标头,排列“Set-Cookie”的所有可能大小写来解决此问题。
这种技术 (hack) 被Zappa 使用,Zappa是一种用 Python 编写的流行的无服务器框架。
晚了几年,但我只需要实现这样的东西,这就是我能够让它工作的方式:
...
//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>");
请注意,在 09/2022 中,AWS Api 网关默认使用一种新的有效负载格式(2.0 版),该格式不再识别所有热门答案(包括接受的答案)提出的multiValueHeaders
。 我只花了 40 分钟试图弄清楚为什么它没有返回我的 cookies:)。
来自 AWS 文档:
格式 2.0 没有 multiValueHeaders 或 multiValueQueryStringParameters 字段。 重复的标题与逗号组合并包含在标题字段中。 重复的查询字符串用逗号组合并包含在 queryStringParameters 字段中。
格式 2.0 包括一个新的 cookies 字段。 请求中的所有 cookie 头都用逗号组合并添加到 cookies 字段中。 在对客户端的响应中,每个 cookie 都变成了一个 set-cookie header。
所以现在的实际解决方案应该是:
return {
statusCode: 302,
headers: {
Location: location,
},
cookies: [
"cookie1=value1;",
"cookie2=value2;"
]
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.