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

fix: api routes not receiving real host, leading to localhost redirect after login

Open MichaelErmer opened this issue 1 year ago โ€ข 13 comments

This fix resolves next auth not using the correct hostname for requests using the API methods, which ultimately led to users being redirected to localhost:3000 after login if next run behind a reverse proxy.

โ˜•๏ธ Reasoning

๐Ÿงข Checklist

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

๐ŸŽซ Affected issues

๐Ÿ“Œ Resources

MichaelErmer avatar Mar 19 '24 15:03 MichaelErmer

Someone is attempting to deploy a commit to the authjs Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Mar 19 '24 15:03 vercel[bot]

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

Name Status Preview Comments Updated (UTC)
auth-docs โœ… Ready (Inspect) Visit Preview ๐Ÿ’ฌ Add feedback Jun 3, 2024 8:23am
1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
next-auth-docs โฌœ๏ธ Ignored (Inspect) Visit Preview Jun 3, 2024 8:23am

vercel[bot] avatar Mar 19 '24 15:03 vercel[bot]

Anything I can do to speed this up?

MichaelErmer avatar Apr 12 '24 20:04 MichaelErmer

Did you enable AUTH_TRUST_HOST (docs) or try the AUTH_REDIRECT_PROXY_URL (docs)?

This should be covered by those two options. Let me know if those still don't work for you :pray:

ndom91 avatar Apr 13 '24 17:04 ndom91

Yes, set both, but still the redirect after idp led to localhost.

MichaelErmer avatar Apr 13 '24 18:04 MichaelErmer

Are you sure you updated the callbackUrl in your OAuth providers dashboard?

We've got an example for Docker up at https://nextjs-docker-example.authjs.dev which does work behind a reverse proxy with all providers :thinking:

ndom91 avatar Apr 14 '24 01:04 ndom91

Are you sure you updated the callbackUrl in your OAuth providers dashboard?

We've got an example for Docker up at https://nextjs-docker-example.authjs.dev which does work behind a reverse proxy with all providers ๐Ÿค”

Do you suggest using an absolute callbackUrl in the signIn call? We are using multiple domains and I think the trust-proxy-option should enable the auth to use the domain from x-forwarded-for ๐Ÿค”

Our IDP (Cognito) is accepting multiple callback URLs, however, without the changes above, the next auth was initializing the signIn with localhost:3000 as callback... We tried both the ENV vars you mentioned and all combinations.

MichaelErmer avatar Apr 14 '24 08:04 MichaelErmer

@MichaelErmer ah okay I think I see what you're saying.

No so you don't have to pass an absolute URL to the signIn() call, but you do have to modify your callbackUrl to be the correct (prod?) URL instead of local dev. I'd recommend two apps in your IdP.

We ran into this a few times, I forget if Cognito was one but I assume from what you're saying it is - Twitch, for example, allows adding multiple callbackUrls, but it'll always redirect to the first one. So if you add a local dev callbackUrl (http://localhost:3000/api/auth/twitch) and a prod one (https://app.company.com/api/auth/callback/twitch), it'll always only set the first (local) one as callbackUrl after coming back from the authorization_url redirect, no matter what

If you create two separate OAuth applications in your IdP, you'll just have to use two sets of separate clientId/clientSecret env vars, 1 for dev 1 for prod, just like with Github for example.

ndom91 avatar Apr 14 '24 09:04 ndom91

I understand what you are saying, we wouldn't want our customers to have to setup multiple Apps on their sso for different systems of us, they whitelist only our tld or a list of domains.

This change fixes the issue, in a generic way, by initiating the signIn at the IDP using the (from users perspective) correct return url, whilst ensuring and respecting trust host is enabled etc.

MichaelErmer avatar Apr 14 '24 15:04 MichaelErmer

@ndom91 tried with the latest version, both set AUTH_TRUST_HOST and AUTH_REDIRECT_PROXY_URL, the "login" itself works, BUT after the "login" result is handled at /api/auth/callback/cognito the user is then redirected to https://0.0.0.0:3000/dashboard.

This PR fixes the URL being called after login/logout by next-auth, when login is initialized using something like onClick={() => signIn("cognito", { callbackUrl: "/dashboard" })}

MichaelErmer avatar Jun 03 '24 08:06 MichaelErmer

I can confirm this issue, as I'm running into it too. To be consistent, however, I believe this PR should check the x-forwarded-host like here

@MichaelErmer are you still looking to get this merged? Do you want to update your PR to use that header?

dprothero avatar Sep 05 '24 16:09 dprothero

Without some kind of fix like this, running your Next.js site with NextAuth behind a proxy that doesn't pass the Host header isn't possible that I've been able to determine. Even with AUTH_TRUST_HOST=true, this part of the code isn't even bothering to check the X-Forwarded-Host header.

dprothero avatar Sep 05 '24 16:09 dprothero

UPDATE: I just discovered if I set the AUTH_URL (docs), then I can get it to work.

This PR would still be nice to make things work automatically based on headers, however.

dprothero avatar Sep 05 '24 16:09 dprothero