Closed controversial closed 1 year ago
Great find, currently blocking a major release for us. Related: https://github.com/nextauthjs/next-auth/pull/7443#issuecomment-1677261203
The headers().get('set-cookie') method should not concatenate multiple values into a single comma-separated string
Although the HTTP spec says so, the Headers
spec says the opposite for .get()
:
https://fetch.spec.whatwg.org/#dom-headers-get
Hence the introduction of .getSetCookie()
in the first place. The bug here is that the implementation for it might be wrong.
As for TypeScript, it's still missing from the official types https://github.com/microsoft/TypeScript/issues/55270 but we can probably extend it via edge-runtime
(what Next.js is using) where we can guarantee the existence of this property.
Related: https://github.com/vercel/edge-runtime/issues/536
Also note, Headers.getAll
is non-spec and should not be relied on. It was a platform-specific implementation before the getSetCookie
spec existed (https://github.com/whatwg/fetch/issues/973)
To sum it up, it looks like we have to make sure .getSetCookie()
works as expected. The rest looks good to me.
Upon some further investigation, it turns out that the only (new) issue here is the missing typings for getSetCookie
. The fact that headers().get('set-cookie')
returns something, in this case, is a bug.
You are setting response headers in your middleware, and headers()
is supposed to read request headers. There is already an open issue for it at #52564
So the type is actually out in typescript@5.2.1-rc
https://github.com/microsoft/TypeScript/issues/55270#issuecomment-1683706360 just have to wait until it gets to latest. For now, the workaround is @ts-expect-error
Thanks for looking into it @balazsorban44!
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary releaseProvide environment information
```bash Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 23.0.0: Tue Aug 1 03:25:51 PDT 2023; root:xnu-10002.0.242.0.6~31/RELEASE_ARM64_T6000 Binaries: Node: 20.2.0 npm: 9.8.1 Yarn: N/A pnpm: N/A Relevant Packages: next: 13.4.15 eslint-config-next: 13.4.15 react: 18.2.0 react-dom: 18.2.0 typescript: 5.1.6 Next.js Config: output: N/A ```Which area(s) of Next.js are affected? (leave empty if unsure)
App Router, Middleware / Edge (API routes, runtime), TypeScript (plugin, built-in types)Link to the code that reproduces this issue or a replay of the bug
https://codesandbox.io/p/sandbox/fervent-bird-ylrc3x?file=/app/page.tsx
To Reproduce
headers().get('set-cookie')
in a React Server Component.headers().getSetCookie()
(which can be called, even though its TypeScript definition is missing from Next.js)headers.get('set-cookie')
returns a value (albeit incorrect) for the Set-Cookie header.Describe the Bug
The
headers().get('set-cookie')
method concatenates multiple values into a single comma-separated string, which is incorrect behavior and explicitly violates the HTTP specification:The
headers().getSetCookie()
method returns an empty array whenheaders().get('set-cookie')
does notTypeScript definitions for
headers().getSetCookie()
are missingThis blocks applications from reading cookies that are updated by middleware as part of the same request, which is a common flow for use cases such as token refreshing (see discussions like https://github.com/vercel/next.js/discussions/50374, https://github.com/vercel/next.js/discussions/38650)
Expected Behavior
headers().get('set-cookie')
method should not concatenate multiple values into a single comma-separated stringheaders().getSetCookie()
method (spec) should return a non-empty array, containing the separate values of the multipleSet-Cookie
headersWhich browser are you using? (if relevant)
N/A
How are you deploying your application? (if relevant)
N/A
NEXT-1523