简体   繁体   English

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

[英]How can I send multiple Set-Cookie headers from API Gateway using a proxied Lambda

I'm using API Gateway's Proxy integration to call a Lambda.我正在使用 API 网关的代理集成来调用 Lambda。 The output format specification is this follow JSON format: output 格式规范遵循 JSON 格式:

{
  "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).在一个响应中,我希望设置两个 cookies (两个不同的身份验证 cookie),但 JSON 不允许在headers object 中有两个相同的键(好吧,从技术上讲,大多数库都没有)。

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. RFC 7230指出 Set-Cookie 应特别处理,但我看不出如何通过 API 网关发送多个 Set-Cookie 值。

Does anyone know whether this is possible?有谁知道这是否可能?

As of November 2018 this is possible using the multiValueHeaders field in the response instead of headers (see announcement ).截至 2018 年 11 月,可以在响应中使用multiValueHeaders字段而不是headers (请参阅公告)。

As an example instead of:作为一个例子,而不是:

{
  "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"
  }
}

You can respond with:您可以回复:

{
  "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"]
  }
}

Note that you can use a mix of headers and multiValueHeaders :请注意,您可以混合使用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"]
  }
}

However using the same header in both will mean that the value under headers is dropped.但是,在两者中使用相同的标题将意味着headers下的值被删除。

See the documentation for more details.有关更多详细信息,请参阅文档

When using only the header field (as available prior to Nov 2018) I tried sending the following manually curated JSON as a response:仅使用标头字段(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"
  }
}

The cookies that API gateway returns in response to a CURL request are: 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

As you can see the first Set-Cookie is dropped on the floor.如您所见,第一个Set-Cookie掉在了地板上。

As Mark B pointed out, you can/should achieve this by setting multiple cookie name/value pairs in a single Set-Cookie header.正如 Mark B 指出的那样,您可以/应该通过在单个 Set-Cookie 标头中设置多个 cookie 名称/值对来实现这一点。 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.编辑:正如 OP 所指出的,有些用例需要标头的多个实例。 We've added it our backlog along with supporting multiple header names on incoming requests.我们已将其添加到我们的待办事项中,并支持传入请求的多个标头名称。

Use multiValueHeaders:使用 multiValueHeaders:

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

or:或:

{
    "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 https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format

As answered, to date, API Gateway will drop identical keys, only setting one of the cookies.正如回答的那样,到目前为止,API Gateway 将删除相同的密钥,只设置其中一个 cookie。

However, a workaround exists.但是,存在一种解决方法。 You can change the casing of the string 'Set-Cookie' so the keys are not unique.您可以更改字符串'Set-Cookie'的大小写,因此键不是唯一的。 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.例如,您可以使用键set-cookieSet-cookiesEt-cookie ,并且将保留标头并设置 3 个不同的 cookie。

Because the RFC standard makes headers case-insensitive this should work with all RFC-compliant clients.因为 RFC 标准使标头不区分大小写,所以这应该适用于所有符合 RFC 的客户端。

So, you could rewrite your set-cookie headers, permuting all the possible casings of "Set-Cookie" to get around this.因此,您可以重写 set-cookie 标头,排列“Set-Cookie”的所有可能大小写来解决此问题。

This technique (hack) is employed by Zappa , a popular serverless framework written in Python.这种技术 (hack) 被Zappa 使用,Zappa是一种用 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.每个数组项都将被独立处理,因此您可以使用不同的设置将尽可能多的 cookie 添加到数组中。

ie

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>");

Please note that in 09/2022 AWS Api Gateway by default uses a new payload format (version 2.0) that no longer recognizes multiValueHeaders as proposed by all the top answers, including the accepted answer.请注意,在 09/2022 中,AWS Api 网关默认使用一种新的有效负载格式(2.0 版),该格式不再识别所有热门答案(包括接受的答案)提出的multiValueHeaders I just spent 40 minutes trying to figure out why it doesn't return my cookies:).我只花了 40 分钟试图弄清楚为什么它没有返回我的 cookies:)。

From AWS Documentation:来自 AWS 文档:

Format 2.0 doesn't have multiValueHeaders or multiValueQueryStringParameters fields.格式 2.0 没有 multiValueHeaders 或 multiValueQueryStringParameters 字段。 Duplicate headers are combined with commas and included in the headers field.重复的标题与逗号组合并包含在标题字段中。 Duplicate query strings are combined with commas and included in the queryStringParameters field.重复的查询字符串用逗号组合并包含在 queryStringParameters 字段中。

Format 2.0 includes a new cookies field.格式 2.0 包括一个新的 cookies 字段。 All cookie headers in the request are combined with commas and added to the cookies field.请求中的所有 cookie 头都用逗号组合并添加到 cookies 字段中。 In the response to the client, each cookie becomes a set-cookie header.在对客户端的响应中,每个 cookie 都变成了一个 set-cookie header。

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

So the actual solution should now be:所以现在的实际解决方案应该是:

    return {
      statusCode: 302,
      headers: {
        Location: location,
      },
      cookies: [
         "cookie1=value1;",
         "cookie2=value2;"
      ]
    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用 CDK 中的 Lambda 的情况下从 API 网关发送 JSON 正文 - How to send JSON body from API Gateway without using Lambda in CDK Rails Set-Cookie on json API 响应 - Rails Set-Cookie on json API response 浏览器可以对XSS jquery.getJSON()请求的标头中指定的Set-Cookie做出反应吗? - Can browsers react to Set-Cookie specified in headers in an XSS jquery.getJSON() request? 我该如何签署来自API Gateway和Lambda的响应? - How could I go about signing a response from API Gateway and Lambda? 如何通过 Bjron Holines Store Locator 插件使用 javascript + 已经在系统现有 ColdFusion 代码上为多个域设置 cookie - How can I set a cookie for multiple domains using javascript + already on the system existing ColdFusion code, via Bjron Holines Store Locator plugin 从 API-Gateway 检索 lambda 中的数据 - Retrieving data in lambda from API-Gateway 如何在Google App Engine上使用Python发送JSON格式的Cookie数据? - How can I send JSON-formatted cookie data using Python on Google App Engine? 如何使用Jetty API客户端发送JSON请求? - How can I send a JSON request using Jetty API Client? 如何在Android中发送HTTP基本身份验证标头? - How can I send HTTP Basic Authentication headers in Android? 节点,如何在节点/快速应用上发送响应头? - Node, how can I send response headers on a node/express app?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM