4

I'm aware that 302 redirections in cross-domain situations can make cookies get lost, but the API / Azure Function is on the same domain as the redirectUrl. Considering the following code snippet:

const expirationDate = new Date(Date.now())
expirationDate.setHours(expirationDate.getHours() + 24)

logger.add(`Token cookie expiration date set to: ${expirationDate}`)

const headers = {
   Location: `${auth?.redirectUrl}?clientName=${clientName}`,
   "Set-Cookie": `token=${
      auth?.token
   }; Expires=${expirationDate.toUTCString()}; Path=/;`,
}

After the browser redirects to the redirectUrl, the cookie canno't be found in the browser's Application tab, as it gets lost somehow. I'm guessing that's a specific problem of Azure Functions and that it wouldn't happen if I used express.js, for example. How can I set cookies while 302-redirecting at the same time?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Ericson Willians
  • 7,606
  • 11
  • 63
  • 114

2 Answers2

2

It seems you can no longer set cookies the way you are trying to. It also does not work when you return 200 instead of 302. The newest recommended way does work however.

Working example code:

context.res = {
    status: 302, /* Defaults to 200 */
    // body: responseMessage,
    headers: {
        Location: "https://localhost",
    },
    cookies: [
        {
            name: "token",
            value: "mytokenvalue",
            maxAge: 60 * 10,
            // expires: xxx,
            path: "/"
        }
    ]
};

See also: Better way to set cookies and other repeatable headers in Javascript Http functions

Ericson Willians
  • 7,606
  • 11
  • 63
  • 114
Alex AIT
  • 17,361
  • 3
  • 36
  • 73
  • 1
    It did work, but I can only see the cookies if I don't use the Location redirect, as they get lost in the way even if I do it in the same domain, but now I know the cookies are being set prior to redirecting. Thanks! By the way, I had to use lowercase headers in the response. – Ericson Willians Oct 24 '22 at 20:14
0

I'm posting an additional answer because the process of setting the cookie while redirecting was quite hellish to test and quite hard to make it work.

context.res = {
   status: 303,
   headers: {
      Location: `${auth?.redirectUrl}?clientName=${clientName}`,
   },
   cookies: [
      {
         name: "token",
         value: auth?.token,
         maxAge: 60 * 10,
         path: "/",
         secure: true,
         sameSite: "none",
         domain: ".example.com.br",
      },
      {
         name: "samlAttributes",
         value: JSON.stringify(auth?.samlAttributes),
         maxAge: 60 * 10,
         path: "/",
         secure: true,
         sameSite: "none",
         domain: ".example.com.br",
      },
   ],
}

The path needed to be '/', I had to set it to secure so that chrome wouldn't complain about sending the cookie over HTTPS without specifying it as secure, had to set sameSite to "none" (Very important) as lax doesn't work with post requests (Only with GET requests, but I'm using post), and I also had to specify the domain (Without specifying it, the browser would not redirect the cookie as well).

This brilliant answer helped me a lot to understand the complexity of the sameSite prop and SSO in general.

Ericson Willians
  • 7,606
  • 11
  • 63
  • 114