nuxt-modules / i18n

I18n module for Nuxt
https://i18n.nuxtjs.org
MIT License
1.71k stars 478 forks source link

Cannot set headers after they are sent to the client - i18n cookie + redirect from auth middleware #2980

Open DavidDeSloovere opened 3 months ago

DavidDeSloovere commented 3 months ago

Environment


Reproduction

This is a combination of nuxt i18n and @sidebase/nuxt-auth

Our auth is set up as global, when you visit the root of the site, you are being redirect to the /auth/login page. Later the redirect to the locale specific page (i.e. /fr/auth/login) is executed, using the prefix strategy. Which will also set the i18n_redirected cookie.

The error is not visible in the browser. But is reported in logs (vercel) and sentry (which I integrated).

Screenshot below. Both log entries for /auth/login are from the same request (id). This looks like a 302 redirect followed by the cookie error. (most recents logs are at top)

I patched H3 to output the cookie name. This is how I figured out it was the i18n_redirected cookie that triggered the error.

image

Describe the bug

Add cookie is being set via H3. https://github.com/unjs/h3/blob/50c66ca7c01f0f30bf0adf23a0469dc2cc81c24b/src/utils/cookie.ts#L58

I believe the redirect has already been executed.

Additional context

Ideally there would be a check if the response has been sent/ended.

I'm not sure if I can control which code gets run first. Maybe that could solve the runtime issue (at least for now)

Also not sure if i18n can be disabled if user is not authenticated.

Logs

No response

DavidDeSloovere commented 3 months ago

Minutes after I submitted this, I wondered if the problem isn't the redirect from the auth module.

If I'm correct, sendRedirect is not awaited as it should in https://github.com/sidebase/nuxt-auth/blob/faa039b72da2c64d9c214f0502dea053c7a4ff84/src/runtime/server/services/authjs/nuxtAuthHandler.ts#L176

I patched the auth module, and it's a bit better now. Next error is the almost the same, but for setResponseHeaders Edit: might have been a bit optimistic about the error going away.

Still for the same 'i18n_redirected' cookie. I will try to disable minification.

[nuxt] [request error] [unhandled] [500] Cannot set headers after they are sent to the client
  at ServerResponse.setHeader (node:_http_outgoing:659:11)  
  at setCookie (./chunks/runtime.mjs:2767:20)  
  at writeServerCookie (./chunks/build/server.mjs:1959:14)  
  at writeFinalCookieValue (./chunks/build/server.mjs:1941:7)  
  at _function (./chunks/runtime.mjs:4287:14)  
  at ./chunks/build/server.mjs:198:44  
  at fn (./chunks/build/server.mjs:305:44)  
  at Object.callAsync (./chunks/build/server.mjs:95:55)  
  at ./chunks/build/server.mjs:307:56  
  at Object.runWithContext (./node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:2238:18)