![](/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.