Search code examples
aws-lambdaaws-api-gatewaysetcookiehttpcookie

AWS Lambda Set-Cookie header not setting in the browser


I'm trying to set a cookie in my aws lambda function response. I don't have any header mapping as I'm using lambda proxy integration with API Gateway. The response code looks like this in the lambda function:

exports.handler = async (event) => {     
const response = {
    statusCode: 200,
    "multiValueHeaders": {
    "Set-Cookie": ["gtgm=6c7729687d5ff1a05f1a5dfb15ce3b8fa3f2b590; path=/; expires=Fri, 13-Feb-2032 13:27:44 GMT; secure; HttpOnly; SameSite=None"]
  },
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Headers": "*",
      "Access-Control-Allow-Credentials": true,
    },
  };
  return response;
};

I use fiddler to check the response and I can see the "Set-Cookie..." in the response which leads me to believe that the code above is correct? The issue is that the browser just ignores it and doesn't set any cookies at all except for the AWS DNT cookie. I'm not sure what else to check or if I've missed anything in the cookie config.

This is what my request looks like:

<Button
      onClick={() => {
        fetch(
          "https:mysupercoolapi.com/cookie-test/",
          {
            // credentials: "include",
            headers: {
              "Content-Type": "application/json",
              // "Access-Control-Allow-Credentials": "true",
            },
          }
        )
          .then((response) => response.json())
          .then((data) => {
            console.log(data);
          });
      }}
    >
      Cookie Test
    </Button>

Not sure what I'm missing or where I'm going wrong.


Solution

  • I magaed to figure this one out myself. The setup above was fine but the browser requires you to have the following set properly in order for it to actually set the cookie:

    • In the request: Set "credentials" as include. Depending on what library you're using (fetch would be credentials: "include"). You can see it is commented out in my original post above which is not correct.
    • In the Response header in the Lambda function you need to set you origin e.g., "Access-Control-Allow-Origin": "http://localhost:3002". After testing I switched it to my actual domain. If there's a way to keep this set to the actual domain but still have it work while testing on localhost please let me know.
    • In API Gateway you need to set the CORS values as in the screenshot below to ensure the preflight (OPTINOS) call is made correctly as well. enter image description here

    The key is to have both the request and response headers configured correctly. This is harder to do when using something like AWS but much easier with something like express.js where you can use the middleware.