Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't set multiple cookies in response on v2 #6525

Closed
1 task
michael-land opened this issue Mar 12, 2023 · 10 comments · Fixed by #6973
Closed
1 task

Can't set multiple cookies in response on v2 #6525

michael-land opened this issue Mar 12, 2023 · 10 comments · Fixed by #6973

Comments

@michael-land
Copy link

michael-land commented Mar 12, 2023

What version of astro are you using?

2.1.2

Are you using an SSR adapter? If so, which one?

tried on vercel and node

What package manager are you using?

pnpm

What operating system are you using?

Mac

What browser are you using?

Chrome

Describe the Bug

    Astro.cookies.set(`is_auth`, '1', {
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      expires: addMinutes(new Date(), 5),
      path: '/',
    });
    Astro.cookies.set(`authorization`, accessToken, {
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      expires: addMinutes(new Date(), 5),
      path: '/',
    });

image

image

Link to Minimal Reproducible Example

todo

Participation

  • I am willing to submit a pull request for this issue.
@michael-land michael-land changed the title Can't set multiple cookies in response on vercel adapter Can't set multiple cookies in response on v2 Mar 12, 2023
@Princesseuh
Copy link
Member

Hello! What version of Node are you using? We've recently had a whole dilemma around cookie handling where specific versions of Node behaved differently and stuff, so it would be helpful to know!

@Princesseuh Princesseuh added the needs response Issue needs response from OP label Mar 13, 2023
@michael-land
Copy link
Author

Hello! What version of Node are you using? We've recently had a whole dilemma around cookie handling where specific versions of Node behaved differently and stuff, so it would be helpful to know!

ah, i see. i was using node 18.2, it working after upgrade to 18.5

@Princesseuh Princesseuh removed the needs response Issue needs response from OP label Mar 13, 2023
@jeffdrumgod
Copy link

jeffdrumgod commented Apr 3, 2023

I'm using 18.12 and have the same problem here.

Edited: only in dev mode. Using production mode (after build, using @astrojs/node) works fine

@romanzy313
Copy link

romanzy313 commented May 2, 2023

Please reopen the issue, I am having the same problem as @jeffdrumgod. Setting multiple cookies works in build but not in dev. Really makes it impossible to use cookies while developing.

Running node 18.14.0, astro 2.3.3, @astrojs/node 5.1.2

Edit:
updating node to latest LTS version 18.16.0 or version 20.0.0 makes cookies work in prod and dev. Probably node issue more then anything

@matthewp
Copy link
Contributor

matthewp commented May 2, 2023

Ok, will recheck.

@matthewp matthewp reopened this May 2, 2023
@matthewp
Copy link
Contributor

matthewp commented May 2, 2023

Think a regression happened here. https://github.com/withastro/astro/pull/6355/files

@alex-sherwin
Copy link
Contributor

I'm seeing multiple set-cookie's work in dev and not in prod (nodejs adapter) using current Node LTS v18.16.0 and latest Astro 2.5.5

I'm not even using Astro.cookies at all, this is me directly setting up a Response with a Headers object with multiple set-cookie headers, e.g.

const h = new Headers();
h.append("set-cookie", "cookie1=abc");
h.append("set-cookie", "cookie2=abc");
return new Response("abc", { headers });

Works in dev, but in prod (using Astro's nodejs adapter) only the first set-cookie is used.

Feels like a bug with some naive code grabbing only the first occurrence of a key (e.g. "set-cookie" header name), still digging through Astro code to see if I can find the culprit

@alex-sherwin
Copy link
Contributor

alex-sherwin commented May 27, 2023

And there it is https://github.com/withastro/astro/blob/main/packages/integrations/node/src/nodeMiddleware.ts#L52

res.writeHead(status, Object.fromEntries(headers.entries()));

The line Object.fromEntries(headers.entries()) is too naive and not accounting for the fact that Headers is a special purpose multi-value map (i.e. can contain > 1 value per key), it cannot be converted to a simple object in this manner.

In reading the node spec for response.writeHead https://nodejs.org/docs/latest-v18.x/api/http.html#responsewriteheadstatuscode-statusmessage-headers interestingly it does not explicitly state that the object form of supplying headers can accept an array of values (but the docs for response.setHeader do say this, so I would assume the behavior is the same)

So this needs to be smarter about building a multi-value object of header key/value pairs

Since this issue was about Astro cookies (and what I'm referring to is the nodejs adapter for any headers specifically set on the Response) I'll open a new ticket)

@matthewp
Copy link
Contributor

Multiple set-cookie headers is not supported by the Headers API. If you Google you'll see lots of discussion on this.

@alex-sherwin
Copy link
Contributor

@matthewp, historically that's correct, however, it is now addressed in the official Fetch spec and now supported in undici since 5.19.0 via Headers.getSetCookie()

I opened #7226 and I'm wrapping up a PR now that's based on the built-in Headers.getSetCookie() that I think is a pretty clean solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants