fix: api routes not receiving real host, leading to localhost redirect after login
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
Someone is attempting to deploy a commit to the authjs Team on Vercel.
A member of the Team first needs to authorize it.
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 |
Anything I can do to speed this up?
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:
Yes, set both, but still the redirect after idp led to localhost.
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:
Are you sure you updated the
callbackUrlin 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 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.
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.
@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" })}
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?
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.
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.