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

后端 未结 5 1985
醉话见心
醉话见心 2021-01-17 09:40

I\'m using API Gateway\'s Proxy integration to call a Lambda. The output format specification is this follow JSON format:

{
  \"statusCode\": httpStatusCode,         


        
相关标签:
5条回答
  • 2021-01-17 10:12

    As of November 2018 this is possible using the multiValueHeaders field in the response instead of headers (see announcement).

    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:

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

    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:

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

    0 讨论(0)
  • 2021-01-17 10:14

    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>");
    
    0 讨论(0)
  • 2021-01-17 10:15

    Use 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

    0 讨论(0)
  • 2021-01-17 10:31

    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.

    0 讨论(0)
  • 2021-01-17 10:32

    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.

    0 讨论(0)
提交回复
热议问题