nextauthjs / next-auth

Authentication for the Web.
https://authjs.dev
ISC License
24.07k stars 3.33k forks source link

Lazy initialization and auth() middleware wrapper incompatiblity bug #11450

Open NBandNB opened 1 month ago

NBandNB commented 1 month ago

Environment

System:
    OS: Windows 11 10.0.26252
    CPU: (8) x64 Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
    Memory: 8.72 GB / 31.87 GB
  Binaries:
    Node: 22.5.1 - C:\Program Files\nodejs\node.EXE
    npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (127.0.2651.49)
    Internet Explorer: 11.0.26252.5000
  npmPackages:
    next: 14.2.5 => 14.2.5
    next-auth: ^5.0.0-beta.19 => 5.0.0-beta.19
    react: ^18 => 18.3.1

Reproduction URL

https://github.com/NBandNB/next-auth-middleware-bug

Describe the issue

It seems that there is a bug which is currently making Lazy Initialization of Next Auth incompatible with the auth() wrapper of a middleware function. It results in the following error:

[auth][error] UnknownAction: Cannot parse action at /session. Read more at https://errors.authjs.dev#unknownaction at parseActionAndProviderId (webpack-internal:///(middleware)/./node_modules/@auth/core/lib/utils/web.js:105:15) at toInternalRequest (webpack-internal:///(middleware)/./node_modules/@auth/core/lib/utils/web.js:37:40) at Auth (webpack-internal:///(middleware)/./node_modules/@auth/core/index.js:84:103) at getSession (webpack-internal:///(middleware)/./node_modules/next-auth/lib/index.js:20:60) at handleAuth (webpack-internal:///(middleware)/./node_modules/next-auth/lib/index.js:134:35) at Object.request [as handler] (webpack-internal:///(middleware)/./node_modules/next-auth/lib/index.js:72:28) at eval (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/web/adapter.js:202:31) at AsyncLocalStorage.run (node:async_hooks:346:14) at Object.wrap (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/async-storage/request-async-storage-wrapper.js:83:24) at eval (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/web/adapter.js:189:122)

This appears to be caused by the base path to being improperly set to "/auth" and the path being improperly set to "/session", when those should be "/api/auth" and "/api/auth/session" respectively, somewhere in the call chain to parseActionAndProviderId. To me it looks most likely that this mistake is made in the function getSession in next-auth, but is likely using improperly set config variables from elsewhere.

How to reproduce

Configure NextAuth using lazy initialization and use the auth() wrapper as middleware. My reproduction example does exactly that and is based off the create-next-app template. See the 2nd commit to see all changes that were necessary in order to reproduce this bug.

Expected behavior

The expected behavior is that the auth wrapper properly retrieves the current session and returns it for use in the middleware it is wrapping.

NBandNB commented 1 month ago

Hello, I did understand that is expected however after trying that and removing it I was able to determine that it was resulting the same bug irrespective of the presence of the route handlers at that location which was supported by what I was able to determine in looking through the code that it doesn’t actually make a http request to the route but rather calls the route handler internally. I have still added the route handler export to show that it still results in the same error as described above. Thank You.

From: Shreyan Shukla @.> Sent: Friday, July 26, 2024 11:33 AM To: nextauthjs/next-auth @.> Cc: NBandNB @.>; Author @.> Subject: Re: [nextauthjs/next-auth] Lazy initialization and auth() middleware wrapper incompatiblity bug (Issue #11450)

I dont think you have properly used next auth for this. Or maybe the reproduction URL isn't very specific enough. Would be highly grateful if you could make the repo more precise in the reproduction URL. Incase you have missed out on usage of next-auth, here's how your directory structure should look like: /app/api/auth/[...nextauth]/route.ts OR /pages/api/auth/[...nextauth].ts

— Reply to this email directly, view it on GitHub https://github.com/nextauthjs/next-auth/issues/11450#issuecomment-2253272996 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AQVE6XK22VFVXAPIPKLKEIDZOKI4XAVCNFSM6AAAAABLNOWBL2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENJTGI3TEOJZGY . You are receiving this because you authored the thread. https://github.com/notifications/beacon/AQVE6XIB2QXZFJZIYRBWQZ3ZOKI4XA5CNFSM6AAAAABLNOWBL2WGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTUGJY32I.gif Message ID: @. @.> >

PauloJSGG commented 1 month ago

I think I'm having a similar problem. I get: Error: The Middleware "/src/middleware" must export a middleware or a default function Every time I try to run Auth on lazy

NBandNB commented 1 month ago

I'm not sure that error is necessarily caused in the same place since it seems like it would be encountered earlier than the above mentioned problem. However, it does occur under the same circumstances established above. Additionally I was able to find a workaround for the problem when the error message matched what I have above by adding basePath: "/api/auth to the initialization config. However for this new error the only solution I have found to avoid it is to downgrade from from next-auth version 5.0.0-beta.20 to 5.0.0-beta.19.

See reproduction of new bug here: https://github.com/NBandNB/next-auth-middleware-bug/tree/next-auth-beta-20 Previous bug here: https://github.com/NBandNB/next-auth-middleware-bug/tree/next-auth-beta-19

bsin1 commented 1 month ago

adding basePath: "/api/auth to the initialization config

Legend. This fixed my Cannot parse action at /session error on beta v19.

Waylon-Firework commented 1 month ago

When I use Lazy initialization. The api will show error if called. I installed "next-auth": "^5.0.0-beta.20",

/api/users
export const GET = auth(async (request: NextAuthRequest) => {
}
Lazy initialization:
import NextAuth from "next-auth"
import GitHub from "@auth/core/providers/github"

export const { handlers, auth } = NextAuth(async (req) => {
  console.log(req) // do something with the request
  return {
    providers: [GitHub],
  },
})
image
NBandNB commented 1 month ago

For now it seems like it will work if you manually downgrade to "next-auth": "5.0.0-beta.19", and add basePath: "/api/auth" to your authentication config(right below where you define providers). Hopefully there will be a better fix soon.

csyedbilal commented 2 weeks ago

1+

dclark27 commented 4 days ago

For now it seems like it will work if you manually downgrade to "next-auth": "5.0.0-beta.19", and add basePath: "/api/auth" to your authentication config(right below where you define providers). Hopefully there will be a better fix soon.

Unfortunately this does not work in my case. Same issue here, auth() is not a function after lazily loading, even with the basePath set to '/api/auth'.

fxghqc commented 4 days ago

Unfortunately this does not work in my case. Same issue here, auth() is not a function after lazily loading, even with the basePath set to '/api/auth'.

When using lazy config, auth is an async function that returns a Promise object.

dclark27 commented 3 days ago

@fxghqc thank you!!!

geometricpanda commented 3 days ago

just to help build upon what @fxghqc, this is what i used:

export default async (req: NextRequest) => {
  const session = await auth();
  if(!session) {
      return NextResponse.redirect('/login'); // add your own redirect or whatever here
  }
};