Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hosting Next Auth behind a proxy (Cloudflare Worker) - the OAuth "redirect_uri" is incorrectly set #6526

Closed
zlwaterfield opened this issue Jan 27, 2023 · 3 comments
Labels
question Ask how to do something or how something works

Comments

@zlwaterfield
Copy link

zlwaterfield commented Jan 27, 2023

Question 💬

  • I have an application hosted at frontend.domain.com (fake domain for privacy reasons) on Vercel.
  • I have my website hosted on another provider at site.domain.com
  • I have my root domain running on a Cloudflare worker at domain.com that will proxy some requests to site.domain.com and some to frontend.domain.com based on the path.
  • The frontend application is using Next Auth for authentication with 3 providers (credentials, Google, LinkedIn) - credentials is working fine, the issue is with the OAuth ones (Google and LinkedIn)

My entire application is working correctly except the redirect_uri on the OAuth providers. For some reason the redirect_uri's host is always frontend.domain.com.

I've scoured previous Next Auth issues and Stackoverflow and have not been able to find a solution that works.

I've tried:

  • toggling the trustHost option
  • all combinations of NEXTAUTH_URL and NEXTAUTH_URL_INTERNAL
    • NEXTAUTH_URL=domain.com
    • NEXTAUTH_URL=domain.com and NEXTAUTH_URL_INTERNAL=frontend.domain.com
    • NEXTAUTH_URL=frontend.domain.com and NEXTAUTH_URL_INTERNAL=domain.com
  • setting the callbackUrl directly from the client
  • I've also added https://frontend.domain.com/api/auth/callback/linkedin and https://domain.com/api/auth/callback/linkedin to the "Authorized redirect URLs for your app" in LinkedIn.

No matter what I do, the redirect_uri's host doesn't change.

How to reproduce ☕️

Here is the client request to domain.com/api/auth/signin/linkedin from domain.com/auth/login
Screenshot 2023-01-27 at 12 51 26 PM
Screenshot 2023-01-27 at 12 51 29 PM

And here is the /authorization request to LinkedIn from Next Auth
Screenshot 2023-01-27 at 12 51 37 PM
Screenshot 2023-01-27 at 12 51 41 PM

I'd expect when I set NEXTAUTH_URL to domain.com that the redirect_uri's host should be domain.com.

Contributing 🙌🏽

Yes, I am willing to help answer this question in a PR

@zlwaterfield zlwaterfield added the question Ask how to do something or how something works label Jan 27, 2023
@zlwaterfield
Copy link
Author

zlwaterfield commented Jan 27, 2023

I found the problem. Next Auth doesn't listen for NEXTAUTH_URL when the app is deployed on Vercel. This doesn't make sense and is a bad practice IMO because there are a lot of apps that host behind a proxy and need to customize the NEXTAUTH_URL.

Here is the solution I used to get around it:

export default (req, res) => {
  if (process.env.VERCEL) {
    // prefer NEXTAUTH_URL, fallback to x-forwarded-host
    req.headers["x-forwarded-host"] = process.env.NEXTAUTH_URL || req.headers["x-forwarded-host"]
  }
  return NextAuth(req, res, options) // eslint-disable-line new-cap
}

from: #4509 (comment) (thanks to @jjorissen52).

@balazsorban44
Copy link
Member

Thanks, this has come up in #6647 newly, so we might revisit this issue.

For context, the intention was not to break proxied deployments, but an observation where people were deploying to Vercel with a wrongly set NEXTAUTH_URL, and such, I decided to prefer the platform value over the user-defined one.

As you noted, this doesn't really make sense, but seemed to be the solution for most people at the time. We could re-visit #4509 and add this, and document that you only need to add NEXTAUTH_URL on Vercel, when you have a proxy in front of it. 👍

@RonB
Copy link

RonB commented Apr 3, 2024

@balazsorban44
Hi, I am a bit lost.

This issues has Cloudflare worker in the title but addresses a problem in vercel.
I am deploying a sveltekit app to Cloudflare pages. That domain is www.mydomain.com. I have a backend server (also sveltekit) at api.mydomain.com. I use the @auth/sveltekit client on www and proxy all /auth requests to api.mydomain.com using a handle like this in and use in the hooks.server.ts:

import type { Handle } from '@sveltejs/kit'

const handleAuthProxy: Handle = async ({ event }) => {
    if (event.url.pathname.startsWith('/auth')) {
        const origin = event.request.headers.get("referer");
        // reject requests that don't come from the webapp, to avoid your proxy being abused.
        if (!origin || new URL(origin).origin !== event.url.origin) {
            throw error(403, "Request Forbidden.");
        }
        // build the new URL path with your API base URL, the stripped path and the query string
        const urlPath = `${API_HOST}${event.url.pathname}${event.url.search}`;
        const proxiedUrl = new URL(urlPath);

        // Strip off header added by SvelteKit yet forbidden by underlying HTTP request
        // library `undici`.
        // https://github.com/nodejs/undici/issues/1470
        event.request.headers.delete("connection");

        return fetch(proxiedUrl.toString(), {
            // propagate the request method and body
            body: event.request.body,
            method: event.request.method,
            headers: event.request.headers,
            duplex: 'half'
        }).catch((err) => {
            console.log("Could not proxy API request: ", err);
            throw err;
        });
    } else {
        return resolve(event);
    }
};

This works fine and all /auth calls are proxied to https://api.mydomain.com

In the auth config on the api backend the redirectProxyUrl is set to https://www.mydomain.com
In the api backend the entire process of getting user, account and creating a session works like a charm.

So most of this seems to work, i get the following cookies in the browser:
__Host-authjs.csrf-token = .....
__Secure-authjs.callback-url = https://api.mydomain.com
__Secure-authjs.pkce.code_verifier=....
__Secure-authjs.state=.....

I am not sure if the callback url is correct though.

After that it should redirect to 'www.mydomain.com/welcome after signing but it redirects to 'www.mydomain.com/auth/callback/welcome' . I don't know why that is.

I think I have some basic mis-conceptions on the way the @auth/sveltekit works in this case but I cannot fnd a real solution to hiding next-auth behind a proxy using sveltekit in cloudflare pages. Setting NEXTAUTH_URL_INTERNAL or AUTH_URL_INTERNAL to https://api.mydomain.com does not have any effect.

Any help would be greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Ask how to do something or how something works
Projects
None yet
Development

No branches or pull requests

3 participants