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

llycmphe  于 5个月前  发布在  其他
关注(0)|答案(7)|浏览(47)

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

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

字符串
在一个响应中,我希望设置两个cookie(两个不同的auth cookie),但JSON不允许在headers对象中有两个相同的键(好吧,技术上规范允许,但大多数库不允许)。
RFC 7230指出Set-Cookie应该被特殊处理,但我不知道如何通过API网关发送多个Set-Cookie值。
有人知道这是否可能吗?

wgx48brx

wgx48brx1#

**注意:**API网关现在有一个版本2的有效负载,与这里描述的(以及新API的默认值)有根本的不同。有关here差异的文档。有关更多详细信息,请参阅其他accepted answer from Samuel

截至2018年11月,可以在响应中使用multiValueHeaders字段而不是headers(参见announcement)。
作为一个例子,而不是:

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


请注意,您可以混合使用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"]
  }
}


然而,在两者中使用相同的头将意味着headers下的值被丢弃。
有关详细信息,请参阅文档。
当只使用header字段(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掉在地板上。

aelbi1ox

aelbi1ox2#

请注意,在09/2022中,AWS API Gateway默认使用新的有效负载格式(版本2.0),不再识别所有顶级答案(包括接受的答案)提出的multiValueHeaders。我刚刚花了40分钟试图弄清楚为什么它不返回我的cookie:)。
AWS文档:
格式2.0没有multiValueHeaders或multiValueQueryStringParameters字段。重复的头与逗号组合并包含在头字段中。重复的查询字符串与逗号组合并包含在queryStringParameters字段中。
格式2.0包含一个新的cookie字段。请求中的所有cookie头都用逗号组合并添加到cookie字段中。在对客户端的响应中,每个cookie都成为一个set-cookie头。
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
因此,实际的解决方案现在应该是:

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

字符串

oo7oh9g9

oo7oh9g93#

正如所回答的,到目前为止,API网关将丢弃相同的密钥,只设置其中一个cookie。
但是,存在一种解决方法。您可以更改字符串'Set-Cookie'的大小写,使键不唯一。例如,您可以使用键set-cookieSet-cookiesEt-cookie,并且头将被保留,并且将设置3个不同的cookie。
因为RFC标准使头文件为case-insensitive,所以这应该适用于所有符合RFC的客户端。
所以,你可以重写你的set-cookie头,permuting all the possible casings of "Set-Cookie"来解决这个问题。
这种技术(hack)是employed by Zappa,一种用Python编写的流行的无服务器框架。

mrwjdhj3

mrwjdhj34#

使用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

insrf1ej

insrf1ej5#

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

Cookie: a=1; b=2

字符串
编辑:正如OP所指出的,有些用例需要多个头的示例。我们已经将其添加到我们的backlog中,沿着支持传入请求的多个头名称。

vom3gejh

vom3gejh6#

晚了几年,但我只是需要实现这样的东西,这就是我如何能够使它工作:

...

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

lkaoscv7

lkaoscv77#

对于使用API Gateway V2的用户,您可以使用cookies prop发送多个cookie。

// Make sure to import V2 types from aws-lambda pacakge
import { APIGatewayProxyEventV2, APIGatewayProxyResultV2 } from "aws-lambda";

export async function lambda(event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> {
  return {
    headers: {
      "Content-Type": "application/json"
    },
    cookies: ["cookie1=value", "cookie2=value"], // Provide cookies
    body: JSON.stringify("{ isAuthenticated: true }"),
    statusCode: 200,
  }
}

字符串

相关问题