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

fix(core): use NEXTAUTH_URL when getting the url during initialization

Open ammmze opened this issue 10 months ago โ€ข 9 comments

โ˜•๏ธ Reasoning

When using an oauth based authentication process and the app is configured with a basePath, we need to set the NEXTAUTH_URL environment variable to tell next-auth / auth.js the base authentication path. However, it does not seem to respect it in all scenarios. For example, I am running next-auth v4.24.7 with a basePath configured as /sso and a NEXTAUTH_URL=http://localhost:3000/sso/api/auth. When I perform a signIn('keycloak'), it does send me to my auth provider (keycloak) BUT the redirect_uri gets set to http://localhost:3000/api/auth/callback (note the missing /sso base path).

๐Ÿงข Checklist

  • [ ] ~Documentation~
  • [ ] Tests
  • [ ] Ready to be merged

๐ŸŽซ Affected issues

I think this fixes the following issues (at least for users using v4...sounds like the v5 beta stuff has this issue too):

  • #10009
  • #9984
  • #8841

๐Ÿ“Œ Resources

ammmze avatar Apr 13 '24 00:04 ammmze

The latest updates on your projects. Learn more about Vercel for Git โ†—๏ธŽ

Name Status Preview Comments Updated (UTC)
auth-docs โŒ Failed (Inspect) Apr 13, 2024 0:12am
next-auth-docs โœ… Ready (Inspect) Visit Preview ๐Ÿ’ฌ Add feedback Apr 13, 2024 0:12am

vercel[bot] avatar Apr 13 '24 00:04 vercel[bot]

Hey thanks for your interest! However, we'd like to avoid making changes like this to v4 atm.

Does setting NEXTAUTH_URL to include only the basePath (i.e. http://localhost:3000/sso) work for yuo?

ndom91 avatar Apr 13 '24 17:04 ndom91

Does setting NEXTAUTH_URL to include only the basePath (i.e. http://localhost:3000/sso) work for yuo?

No...that just makes things worse. Doing that makes it so that all the other calls that it makes (i.e. /session, /providers, etc) no longer have the /api/auth base path. For example, it tries to load /sso/session, but should be /sso/api/auth/session.

It is also explained the documentation that if you are using a custom base path that you set this to the full path to the next auth endpoints.

ammmze avatar Apr 14 '24 02:04 ammmze

@ammmze okay gotcha, yeah we changed the default behaviour of that in v5 but I couldn't remember how v4 behaved in detail. Okay let me have a think abuot this, because changing this now will almost certainly break other peoples existing setups.. :thinking:

ndom91 avatar Apr 14 '24 09:04 ndom91

@ndom91 I can make the change a little more involved if we want by changing the behavior of parse-url so that it still uses the protocol and hostname of the given url (the origin) but then also parses the NEXTAUTH_URL. If the given url has a pathname other than /, then we use that as the default path instead of /api/auth. If the pathname of the given url has a pathname of /, then it would preserve the existing behavior.

The current proposed fix would always result in the NEXTAUTH_URL being used as the protocol and hostname. But the change I described above would preserve the origin information, while only taking the path from the NEXTAUTH_URL if it is something with a base path.

ammmze avatar Apr 15 '24 18:04 ammmze

For clarity in the proposed alternative solution, i've implemented it on a separate branch found here. Effectively it just makes it so that the parseUrl function uses the NEXTAUTH_URL to get the default path instead of hard coding it to /api/auth

ammmze avatar Apr 15 '24 21:04 ammmze

Oye...as I continue to dig at this I have made another discovery...

Previously I had assumed the request "origin" would never have a path*. However, apparently we override the origin of the request when making it an "InternalRequest". And then while digging into that detectOrigin method I discovered that having ANY value set for AUTH_TRUST_HOST will actually enable AUTH_TRUST_HOST. So setting it to 'false' (string because its an env var) will enable that. And so then it falls into that condition which just uses the forwarded host from the request instead of the NEXTAUTH_URL.

So I see 2 issues here:

  1. AUTH_TRUST_HOST doesn't allow you to set it to typical falsy value to disable it. Side note: this env var doesn't seem to be documented anymore.
  2. detectOrigin effectively does not respect the base path configured via setting NEXTAUTH_URL (and neither does parseUrl, which may be fixed with something like this.

But I guess the good news is I think I am now un-blocked from this issue by removing the AUTH_TRUST_HOST environment variable.

[!NOTE] *origin typically just contains protocol, host, and sometimes the port. Example:

> new URL('https://example.com/foo').origin
'https://example.com'

ammmze avatar Apr 19 '24 22:04 ammmze

I have a similar issue, that leads me to be constantly redirected back to my sign-in page or my local host.

My production environment is a docker swarm, with caddy infront of it. It works locally, but not in my prod.

smultar avatar Apr 22 '24 04:04 smultar

I have the very same issue. Cannot use either signIn() or signOut(). I need signOut() to implement the logout

TomWonder avatar May 09 '24 16:05 TomWonder