next-auth icon indicating copy to clipboard operation
next-auth copied to clipboard

NextAuth v5 `auth(req, res)` fails in `pages/` API route

Open howard36 opened this issue 1 year ago • 25 comments

Environment

$ npx envinfo --system --binaries --browsers --npmPackages "{next,react,next-auth,@auth/*}"
  System:
    OS: macOS 14.0
    CPU: (8) arm64 Apple M2
    Memory: 590.48 MB / 16.00 GB
    Shell: 3.6.1 - /opt/homebrew/bin/fish
  Binaries:
    Node: 18.18.0 - ~/.local/share/nvm/v18.18.0/bin/node
    Yarn: 1.22.19 - ~/.local/share/nvm/v18.18.0/bin/yarn
    npm: 9.8.1 - ~/.local/share/nvm/v18.18.0/bin/npm
    pnpm: 8.11.0 - ~/.local/share/nvm/v18.18.0/bin/pnpm
  Browsers:
    Chrome: 119.0.6045.199
    Safari: 17.0
  npmPackages:
    next: latest => 14.0.3 
    next-auth: 5.0.0-beta.2 => 5.0.0-beta.2 
    react: ^18.2.0 => 18.2.0 

Reproduction URL

https://github.com/howard36/next-auth-v5-example/tree/api-route-bug-repro

Describe the issue

I have a API route at pages/api/endpoint.ts:

import type { NextApiRequest, NextApiResponse } from "next";
import { auth } from "auth";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const session = await auth(req, res);
  return res.status(200).json({session});
}

Calling auth(req, res) in this API route causes this error:

 ⨯ Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/howard/git/next-auth-v5-example/node_modules/next/headers' imported from /Users/howard/git/next-auth-v5-example/node_modules/next-auth/lib/index.js
Did you mean to import next-auth-v5-example/node_modules/next/headers.js?
    at new NodeError (node:internal/errors:405:5)
    at finalizeResolution (node:internal/modules/esm/resolve:327:11)
    at moduleResolve (node:internal/modules/esm/resolve:946:10)
    at defaultResolve (node:internal/modules/esm/resolve:1132:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:835:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
    at link (node:internal/modules/esm/module_job:76:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

This is with next-auth 5.0.0-beta.2, next 14.0.3, and node 18.18.0. If I switch to nextjs v13 (specifically v13.5.6), the error changes to:

 ⨯ node_modules/next-auth/lib/index.js (117:0) @ eval
 ⨯ TypeError: Cannot read properties of undefined (reading 'append')
    at eval (webpack-internal:///(api)/./node_modules/next-auth/lib/index.js:128:52)
    at Array.forEach (<anonymous>)
    at cloneSetCookie (webpack-internal:///(api)/./node_modules/next-auth/lib/index.js:128:21)
    at eval (webpack-internal:///(api)/./node_modules/next-auth/lib/index.js:73:13)
    at async handler (webpack-internal:///(api)/./pages/api/endpoint.ts:11:21) {
  page: '/api/endpoint'
}
null

How to reproduce

git clone -b api-route-bug-repro https://github.com/howard36/next-auth-v5-example.git
cd next-auth-v5-example
npm install
cp .env.local.example .env.local
npm run dev

Then visit http://localhost:3000/api/endpoint to trigger the error

Expected behavior

Calling auth(req, res) should successfully return the session without throwing an error.

howard36 avatar Dec 03 '23 23:12 howard36

I'm seeing this as well with next-auth beta4 and next 14.0.4

jonluca avatar Dec 07 '23 22:12 jonluca

looks like the new authjs beta v5 is not designed for the pages router, only works for the app router

JasonZhLiang avatar Dec 11 '23 17:12 JasonZhLiang

Docs say pages is still supported

https://authjs.dev/guides/upgrade-to-v5

I think it's just a messed up import. Maybe making it an asynchronous conditional import inside the RSC check would fix it?

jonluca avatar Dec 11 '23 17:12 jonluca

This was working in next.js v13 and after upgrade to next.js v14 it's not working.

I think import of RSC-only Next.js packages (next/headers) in next-auth package cause the error. As jonluca suggested, I suppose making those imports dynamic would solve the issue.

pinelibg avatar Dec 13 '23 02:12 pinelibg

Seems like the V5 beta removed the conditional loading of next/headers only for RSC (which was added in a certain minor/patch version of V4), so people using pages router (like myself) essentially can't work with nextauth right now (which is a bummer because I just upgraded in order to be able to use the edge runtime). Moving to app router may not be the way to go for everyone, as some would like to stay with tRPC and spamming "use client" in every file seems a little bit counter-intuitive...

glenntws avatar Dec 22 '23 01:12 glenntws

Hey @balazsorban44 it looks like the issue was first introduced here https://github.com/nextauthjs/next-auth/commit/65aa467c0e02c58fc37aa7559038102d18f7f3f0 at this file https://github.com/nextauthjs/next-auth/blame/main/packages/next-auth/src/lib/index.ts#L2

Is it intentional that next-auth v5 should no longer work with pages router?

jonluca avatar Dec 22 '23 23:12 jonluca

im facing the same issue, i am using an api which needs to be used in pages router, and auth() is not working there, what are the odds if next-auth is supported in pages router or not from now? i have lot of dependencies i dont want to downgrade my versions now, but can i know till which version is it compatible? i am using next 14.0.1 and next-auth@v5 beta .4

me-imfhd avatar Dec 23 '23 08:12 me-imfhd

Same issue here, did anyone managed to fix this?

JustJoostNL avatar Dec 31 '23 15:12 JustJoostNL

There is no solution for this at the moment, it seems. Try switching to app router until there's a fix.

cfkarakulak avatar Jan 03 '24 13:01 cfkarakulak

I found a temp. solution for this issue by modifying these 2 files : (NextProject)\node_modules\next-auth\lib\index.js (NextProject)\node_modules\next-auth\lib\actions.js

in actions.js file: add .js extension to the path 'next/headers' and 'next/navigation'

import { headers as nextHeaders, cookies } from "next/headers";
import { redirect } from "next/navigation";

to

import { headers as nextHeaders, cookies } from "next/headers.js";
import { redirect } from "next/navigation.js";

in index.js file: add .js to the path 'next/headers' and 'next/server'

import { headers } from "next/headers";
import { NextResponse } from "next/server";

to

import { headers } from "next/headers.js";
import { NextResponse } from "next/server.js";

and in function initAuth(config) you will find it in line 32 in index.js file : comment/disable these 2 lines that add auth cookies to response as we just need to get session from our req and ignore res headers :

for (const cookie of authResponse.headers.getSetCookie())
     response.headers.append("set-cookie", cookie);

yousifsamir0 avatar Jan 07 '24 20:01 yousifsamir0

I found a temp. solution for this issue by modifying these 2 files : (NextProject)\node_modules\next-auth\lib\index.js (NextProject)\node_modules\next-auth\lib\actions.js

That's great but how do you do deploy this given that the changes you suggest are in a dependency?

(I know a fork is a potential solution but would rather not have to deal with that overhead.)

julienben avatar Jan 17 '24 21:01 julienben

@julienben For the time being you can patch your package using: https://www.npmjs.com/package/patch-package. But for me after applying the fix of @yousifsamir0 I get null when I call await auth(req, res) from an api route

AlessandroAries avatar Jan 27 '24 18:01 AlessandroAries

I changed the line

response.headers.append("set-cookie", cookie);

to:

if('headers' in response) {
     response.headers.append("set-cookie", cookie);
} else {
    response.appendHeader("set-cookie", cookie);
}

because I didn't know if the first method could be used in other part of the code; in any case it worked for me

stefanoimperiale avatar Jan 31 '24 13:01 stefanoimperiale

Having the same issue here, discovered it while trying to use getServerSideProps. My app is pages/app hybrid, we were planning on migrating to auth.js, but of course migrating everything to the app router is not an option right now.

fabiopk avatar Jan 31 '24 20:01 fabiopk

I don't understand why the maintainers of this repo don't mark with bold letters so that devs who are working with pages infrastracture don't waste their time migrating....

⛔️ Warning, auth.js v5 is not compatible with pages router as of today

This issue has been open since December 3. @balazsorban44 Could we get some kind of a warning in the repo? Or possibly an actual fix to this issue 😅

avarayr avatar Feb 05 '24 03:02 avarayr

@avarayr agree especially since on the documentation page we have App Router-first (pages/ still supported). as a feature!

dengelke avatar Feb 05 '24 03:02 dengelke

@avarayr @dengelke appreciate you both trying to be helpful, but we have multiple people receiving alerts from this issue, v5 is not production ready, if you go to https://next-auth.js.org/getting-started/example you won't see any reference to v5 yet, so it makes no sense complaining about warning on this version since it already says Experimental and you can only install forcing it to be beta.

this issue is already open, pretty sure balazsorban44 is going to address or share updates once he has, and the project is always open to fork and send PRs, is not an easy task to maintain large/complex projects like this one, so let's try to be respectful to each other's time.

maiconcarraro avatar Feb 05 '24 20:02 maiconcarraro

@avarayr @dengelke appreciate you both trying to be helpful, but we have multiple people receiving alerts from this issue, v5 is not production ready, if you go to next-auth.js.org/getting-started/example you won't see any reference to v5 yet, so it makes no sense complaining about warning on this version since it already says Experimental and you can only install forcing it to be beta.

this issue is already open, pretty sure balazsorban44 is going to address or share updates once he has, and the project is always open to fork and send PRs, is not an easy task to maintain large/complex projects like this one, so let's try to be respectful to each other's time.

With all due respect, there's no indication of auth.js not being production ready. Please link one resource that explicitly says to not use auth.js in production.

FWIW, not being production ready is completely irrelevant to this issue. I don't really care if you think this library is experimental, if it has the features I want to use, and I have a way to vet the code myself, why shouldn't I use it? The issue is the docs saying pages are supported, but it actually is not working. So having a clear warning would save people time trying to make v5 work in their apps, even if it's just a hobby project that doesn't require "production-ready state"

avarayr avatar Feb 05 '24 20:02 avarayr

Contributor/maintainer burnout is a real thing. Please be respectful of people's time and work and don't place expectations on code that you get for free.

julienben avatar Feb 06 '24 17:02 julienben

tad bit excessive, considering people who also spend time on developing things, only to find out v5 is not compatible with the system they have.

cfkarakulak avatar Feb 06 '24 18:02 cfkarakulak

tad bit excessive, considering people who also spend time on developing things, only to find out v5 is not compatible with the system they have.

You can downgrade to v4 while it doesn't have a proper solution yet, I'm currently using v4 in production. It works great w/ pages.

The migration between v4 and v5 is simple. And if you are on next-auth website it only says v4, not v5, if you are in authjs website it has a big warning "Guides are being migrated" + "site is under active development". I doubt you guys really read the documentation. Note that https://next-auth.js.org/guides and https://authjs.dev/guides have different states and warnings

If you have the issue, just follow the instructions and open a new issue, please stop using this issue as social media, open a discussion topic instead.

maiconcarraro avatar Feb 06 '24 18:02 maiconcarraro

No need to be this aggressive, this whole thread seems to have started as an issue, thinking if the developers are doing something wrong integrating v5, or a presence of a bug that hasn't yet been discovered. It was not until a couple of us figured it out that it was actually not working. (to make it clearer to you, this is the point where it turned into a discussion).

Anyhow, let's stop arguing at this point. You already have the necessary links and guidance for the ones who seek to get this right.

Thanks

cfkarakulak avatar Feb 06 '24 18:02 cfkarakulak

Well, if there's something that can be done is to update the page that says this is supported in v5 as mentioned above; even if the tone wasn't right, the point is clear. If it doesn't work, don't say it does. I landed in the brand new AuthJS page and by default the experimental version is checked which doesn't happen in any other framework/library... I've just noticed v4 for the actual next auth has a different site (i assume that's the original one, first time using this), but this repo points you to the new one (rather confusing).

Summing this all up, the migration process is being handled poorly and that's just something to learn from. Perhaps better clarification / onboarding to the ecosystem is just what's needed here. Also leaving next auth v4 in its own repo and pointing that to the original next auth site would've been more clear.

To be fair, many projects handle this poorly. It was (is lol) the same with NextJS's app directory... And if you think about it, that's the entire reason why we are here.

No rush to patch / fix anything, but updating that section in the documentation can be done right away. For my use case I 100% need to use auth() in /pages/api. I chose v5 because I read exactly what was linked above.

wiredmatt avatar Feb 08 '24 23:02 wiredmatt

I found a temp. solution for this issue by modifying these 2 files : (NextProject)\node_modules\next-auth\lib\index.js (NextProject)\node_modules\next-auth\lib\actions.js

in actions.js file: add .js extension to the path 'next/headers' and 'next/navigation'

import { headers as nextHeaders, cookies } from "next/headers";
import { redirect } from "next/navigation";

to

import { headers as nextHeaders, cookies } from "next/headers.js";
import { redirect } from "next/navigation.js";

in index.js file: add .js to the path 'next/headers' and 'next/server'

import { headers } from "next/headers";
import { NextResponse } from "next/server";

to

import { headers } from "next/headers.js";
import { NextResponse } from "next/server.js";

and in function initAuth(config) you will find it in line 32 in index.js file : comment/disable these 2 lines that add auth cookies to response as we just need to get session from our req and ignore res headers :

for (const cookie of authResponse.headers.getSetCookie())
     response.headers.append("set-cookie", cookie);

Does anyone knows the impact of doing what is suggested by @yousifsamir0 above? I quickly tested it and it seems to fix the problem of it not working on the pages router. I was already doing the migration for my app, and unfortunately started by the app router portion. Wondering if it is viable to patch as mentioned above and continue developing for the meanwhile. I imagine that some other portions might break by removing some lines of code, just wondering how things would differ in my development between that version and a proper fix.

Thanks :)

fabiopk avatar Feb 09 '24 14:02 fabiopk

I created a patch-package for this issue. This handles my basic use case of using next-auth on an application with hybrid pages/app router handlers. This is just a temporary fix for those who wants to try out the latest features before they are officially released.

Save this as patches/next-auth+5.0.0-beta.9.patch (cannot upload the file, so just manually save this on your repo)

diff --git a/node_modules/next-auth/lib/index.js b/node_modules/next-auth/lib/index.js
index c2b9043..b02bfb4 100644
--- a/node_modules/next-auth/lib/index.js
+++ b/node_modules/next-auth/lib/index.js
@@ -106,8 +106,15 @@ export function initAuth(config, onLazyLoad // To set the default env vars
         // @ts-expect-error
         new Headers(request.headers), config).then(async (authResponse) => {
             const auth = await authResponse.json();
-            for (const cookie of authResponse.headers.getSetCookie())
-                response.headers.append("set-cookie", cookie);
+            for (const cookie of authResponse.headers.getSetCookie()) {
+		if ("headers" in response) {
+                	response.headers.append("set-cookie", cookie);
+	        // This should handle correct header addition on Next.JS API routes
+		} else {
+			response.appendHeader("set-cookie", cookie)
+		}
+	    }
+		
             return auth;
         });
     };

You can then call this inside your api routes as:

// make sure to supply req, res since we are on pages router and not app router
const session = await auth(req, res)

Thanks to @stefanoimperiale for the original code

bnsngltn avatar Feb 18 '24 04:02 bnsngltn

looks like the new authjs beta v5 is not designed for the pages router, only works for the app router

Also in example of next-auth-v5 they use only App Router

chistyakofff avatar Feb 22 '24 02:02 chistyakofff

hey everyone, I want to confirm that we are not dropping the Pages Router support in v5. I'm working on the fix in the linked PR, appreciate the digging @stefanoimperiale, @bnsngltn and all 🙏

ThangHuuVu avatar Feb 24 '24 04:02 ThangHuuVu

Lead maintianer here. Please hold your horses... v5 is in beta, the expected behavior is that things work in the Pages Router, as documented and mentioned above.

The project is open-source, open for PRs. Please only engage in the discussion if you have something net positive/meaningful to add. Guessing what is and isn't supposed to be supported is counter productive. If you just follow the issue, subscribe to it or 👍 the OG post instead.

https://github.com/nextauthjs/next-auth/issues/9307#issuecomment-1930525645 put it very nicely

balazsorban44 avatar Feb 24 '24 14:02 balazsorban44

I am little bit confused. Did the PR fixed this issue? I am currently using 5.0.0-beta.15. Still see this issue.

kwu-soundhound avatar Mar 15 '24 03:03 kwu-soundhound

@kwu-soundhound please open a new issue with minimal reproduction if you're still seeing it, thanks!

ThangHuuVu avatar Apr 25 '24 16:04 ThangHuuVu