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

Encode isn't an option in Cookie #64346

Open
c0d3rm0n opened this issue Apr 11, 2024 · 8 comments
Open

Encode isn't an option in Cookie #64346

c0d3rm0n opened this issue Apr 11, 2024 · 8 comments
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Runtime Related to Node.js or Edge Runtime with Next.js.

Comments

@c0d3rm0n
Copy link

Link to the code that reproduces this issue

https://github.com/c0d3rm0n/test-set-cookies

To Reproduce

I'm creating an app that uses third party libraries that use Go and set / send their cookies in raw format, and they expect to receive them in the same format.

I use those services in my server actions, and then I have to set the cookies they send inside of response headers. As result of this action, the cookie(s) sent to my server will be set in my browser.

However, the function cookies().set({...my_cookie}) from next/headers will encode the cookie and the value set will not match the original one, causing my calls to those 3rd party libs to fail or give error.

From what I could find, encode should be an option of Cookie, and in next.js modules it is possible to find an interface that includes it (CookieSerializeOptions) but then, the other interfaces that use it don't include encode... So, even if I try to set a cookie like cookies().set({...my_cookie, encode: String}) the browser record will be encoded.

The same happens in Middleware, using nextResponse.cookies.set({...my_cookie}).

Current vs. Expected behavior

I would like to be able to set a cookie and define the encoding function in it's options.

For example, the function cookies().set({...my_cookie, encode: String}) should accept encode as option and save a value like
qwerty123=
and not
qwerty123%3D
as it is saving at the moment...

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
Binaries:
  Node: 20.11.0
  npm: 10.2.4
Relevant Packages:
  next: 14.1.4
  eslint-config-next: 14.1.4
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.4.4
Next.js Config:
  output: standalone

Which area(s) are affected? (Select all that apply)

Middleware / Edge (API routes, runtime)

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

No response

@c0d3rm0n c0d3rm0n added the bug Issue was opened via the bug report template. label Apr 11, 2024
@github-actions github-actions bot added the Runtime Related to Node.js or Edge Runtime with Next.js. label Apr 11, 2024
@xluk9
Copy link

xluk9 commented Apr 15, 2024

Yeah, I'm having the same error in my codebase. Lost hours.
For now I'm returing them from server action and setting them in client component with document.cookie=.....

@c0d3rm0n
Copy link
Author

I ended up creating route handlers (API) so I can serialize the cookies and set them in my response header.
This should be possible to do in server actions as one of its intent is to create a shortcut for server handlers instead of creating API routes. For me it is a bit disappointing to create these route handlers to deal with some form submits instead of making all of my 3rd party calls by server actions...
I really think that it should be possible to set the encode function as a cookie option. If you want to use something different from the default encode method, why not do it if it is an option that is referred in cookie standard?

@c0d3rm0n c0d3rm0n reopened this Apr 16, 2024
@ejasarevic
Copy link

Same issue here, would be useful to have a way to specify custom "encode" function whenever we don't want to use encodeURIComponent which is default one.

@github-actions github-actions bot added the linear: next Confirmed issue that is tracked by the Next.js team. label Jun 10, 2024
@wyattjoh
Copy link
Member

wyattjoh commented Jul 4, 2024

We're looking into this particular use case now. It may be possible to modify the encode property in the future for the cookies().set(). We're investigating this now.


Bear in mind that RFC2109 requires that the cookie value either be a:

  1. quoted-string (see RFC2109#4.1):
          quoted-string  = ( <"> *(qdtext) <"> )

          qdtext         = <any TEXT except <">>
  1. token (see RFC2068#2.2):
          token          = 1*<any CHAR except CTLs or tspecials>

          tspecials      = "(" | ")" | "<" | ">" | "@"
                         | "," | ";" | ":" | "\" | <">
                         | "/" | "[" | "]" | "?" | "="
                         | "{" | "}" | SP | HT

This would mean that if the user sets a cookie via cookies().set(), and specifies a encode: String option, they must quote the string if it contains special characters like =. If these aren't encoded according to the spec, then the risk of other parsers not correctly handling the cookie parsing logic is high.

@DrewLandgraveCbsi
Copy link

@wyattjoh any updates on this? We're having to create an api route to set cookies for a client because their backend doesn't decode the cookie string before ingesting.

Frustrating and I'm hoping to get them to update their code but if the cookies().set() method would allow us to override the encoding that would be super helpful

Thanks!

@aaronzhongg
Copy link

aaronzhongg commented Aug 26, 2024

I was able to work around this issue by manually appending the Set-Cookie header instead of using response.cookies.set(), but I agree that exposing the encode function would be ideal

response.headers.append(
          "Set-Cookie",
          `${cookie.name}=${cookie.value}; Path=/; HttpOnly; Secure; SameSite=None;`,
        );

See mdn docs for more info

@DrewLandgraveCbsi
Copy link

Docs say it's available now https://nextjs.org/docs/app/api-reference/functions/cookies

However the types for 15.0.3 don't.
Screenshot 2024-12-02 at 3 25 50 PM

@Juuldamen
Copy link

Juuldamen commented Dec 13, 2024

Taking a quick glance it seems this is not implemented yet for the edge runtime. Within @edge-runtime/cookies v6.0.0 used by Next.js 15.1.0 it is always calling encodeURIComponent. I haven't looked at other runtimes so maybe those have it implemented.

https://github.com/vercel/edge-runtime/blob/440c123a37284d6a852ce453af810ad484ecfc01/packages/cookies/src/serialize.ts#L21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Runtime Related to Node.js or Edge Runtime with Next.js.
Projects
None yet
Development

No branches or pull requests

7 participants