Skip to content

Order of headers in Response from middleware differs from vanilla implementation #606

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

Open
NickCrews opened this issue Apr 25, 2025 · 5 comments
Labels
question Further information is requested

Comments

@NickCrews
Copy link

Describe the bug

Thank you for your help! I am excited to migrate my app to cloudflare.

See nextauthjs/next-auth#12909

Basically, the cloudflare runtime returns the two set-cookie headers in a different order than in vanilla next (eg with next dev or when deployed to vercel). This leads to the logout behavior being broken on cloudflare for any app that uses authjs.

Now, I don't think this is REALLY your problem. authjs should only be returning a single set-cookie header. But, you are stuck with the result, and there are probably many other libraries out there that are doing this incorrect behavior (returning multiple set-cookie headers with the same name), and all of their users are probably used to them working on eg vercel. So unfortunately, if you want users to be happy to switch from vercel to cloudflare, you could consider

  1. update your behavior to follow vanilla
  2. collaborate with vanilla to make an official spec for this behavior, possibly only including the last-set cookie in the Response.

Steps to reproduce

See linked issue

Expected behavior

The headers to be returned in the same order as in vanilla.

@opennextjs/cloudflare version

1.0.0-beta.3

Wrangler version

4.13.2

next info output

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:30 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6000
  Available memory (MB): 65536
  Available CPU cores: 10
Binaries:
  Node: 23.5.0
  npm: 10.9.2
  Yarn: N/A
  pnpm: 10.2.1
Relevant Packages:
  next: 15.1.1-canary.6 // There is a newer canary version (15.4.0-canary.10) available, please upgrade! 
  eslint-config-next: 15.1.3
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.8.3
Next.js Config:
  output: N/A
 ⚠ There is a newer canary version (15.4.0-canary.10) available, please upgrade! 
   Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
   Read more - https://nextjs.org/docs/messages/opening-an-issue

Additional context

No response

@NickCrews NickCrews added bug Something isn't working triage labels Apr 25, 2025
@vicb
Copy link
Contributor

vicb commented Apr 29, 2025

Could you please include a minimal repro (link to a GH repository) with instructions on how to reproduce.

@vicb vicb added waiting for feedback question Further information is requested and removed triage bug Something isn't working labels Apr 29, 2025
@vicb vicb changed the title [BUG] Order of headers in Response from middleware differs from vanilla implementation Order of headers in Response from middleware differs from vanilla implementation Apr 29, 2025
@NickCrews
Copy link
Author

See https://github.com/NickCrews/next-auth-example/tree/cloudflare-nextauth-header-repro. The steps are in the readme.

@conico974
Copy link
Collaborator

OpenNext actually gives you more flexibility on this one than default Next, you can actually choose on a per-request basis which headers/cookies takes precedence between the middleware and the handler. With default Next you're stuck with whatever Next/Vercel decides for you.

We should probably add some docs around this.

Just change your open-next.config.ts to

import { defineCloudflareConfig } from "@opennextjs/cloudflare/config";
import type { OpenNextConfig } from "@opennextjs/cloudflare/config";

const config =  defineCloudflareConfig();

export default{
  ...config,
  dangerous: {
    // This one would do the trick for you for example
    // You could also always return "handler" 
    headersAndCookiesPriority(event) {
      if(event.method === "POST" && event.headers['next-action']) {
        return "handler";
      }
      return "middleware"
    },
} satisfies OpenNextConfig

@NickCrews
Copy link
Author

Thanks @conico974, that is an excellent workaround.

I am curious if we can make the default open-next.config.ts behavior match that of next/vercel? Or the reason why opennext decided with the current behavior of defaulting to middleware? My git kung fu isn't good enough to follow this backwards to find the commit/PR that added this. Also that code is in the AWS adapter, does cloudflare inherit behavior from there?

@conico974
Copy link
Collaborator

Cloudflare uses the aws adapter under the hood.

It was implemented a while back, and the main reason it is this way is to allow to override some headers that Next set (and does/did not allow to override). And as you mentionned, doing what auth.js is not exactly great or recommended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Development

No branches or pull requests

3 participants