Next.js production build cannot login -- landing on `/response_mode=query` resulting in 404

I have a Solid App with React and Next.js. It works fine with development build.

However, when trying to make it a production build (to publish to github pages), there are problems with log-in.
In particular, after calling log-in function with IDP, it jumps and lands on a 404 page on my site.
The URL for that page is: http://localhost:3000/response_mode=query.

After examining the network trace, it seems to be a mis-redirect somehow. The correct URL should be the following (found when running in development build):

https://SOLID_SERVER/.oidc/auth?client_id=CLIENT_ID&redirect_uri=http://localhost:3000/&response_type=code&scope=openid offline_access webid&state=STATE_VALUE&code_challenge=CODE_CHALLENGE_VALUE&code_challenge_method=S256&prompt=consent&response_mode=query

(I hid some potentially sensitive values with UPPER_CASE_WORDS.)

The network traffic were exactly the same until https://SOLID_SERVER/.well-known/openid-configuration. The next one is different, as described above.

Does anyone have similar experience?

A guess is next.js tried to minify the library, which led to this problem. However, even if disabling minify, nothing changed.
I disabled minify by having my next.config.js as (following this; hope it’s correct):

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  optimization: {
    minimize: false
  },
}

module.exports = nextConfig

Just an initial shot in the dark: maybe deleting all your cookies and local storage data on your app domain and solid pod domain could help (or try it in private mode). Sometimes this can fix weird redirect issues…

Minification or the use of Next.js shouldn’t be a problem; my app is also built on Next.js, and logging in works just fine.

You’ll probably want to share the code you use to login with us. My first hunch would be to inspect the redirectUrl that you’re providing.

2 Likes

Hi @renyuneyun, I agree with Vincent, if your app is open source or if you can share a code snippet of the login call with us that would be helpful.

If things are working locally, but not once deployed, the redirect URL provided to the login call may be a good place to look at indeed. Can you elaborate on the flow that happens locally? Is the window redirected to the OpenID Provider, where you can log in successfully before experiencing the 404 once logged in?

1 Like

Thanks @Vincent and @zwifi. I’ll elaborate here.

The log-in button code is available at here. As you see, it uses @inrupt/solid-ui-react.
(Please ignore the “log-in using WebID” part below that. This app has some legacy code not maintained by me, and I haven’t had time to clean them up – it’s not working anyway.)

The redirect URL is a context baseUrl, set in this part in index.js. The reason I use it is because the github pages may be in a path under a domain (e.g. https://a.b.c/d) rather than without one (e.g. https://a.b.c). Maybe there is a better way that I’m not aware of.

Just to clarify: it works with development mode (i.e. next dev). Even locally with production mode (i.e. next build && next start), it will not work.

The working flow is:

  1. Fill in IDP
  2. Click log-in button
  3. Redirect to IDP’s log-in page
  4. Log-in, etc

The wrong flow I encounter is:

  1. Fill in IDP
  2. Click log-in button
  3. Redirect to http://localhost:3000/response_mode=query, resulting in 404
    the http://localhost:3000 is where the App is running; it will be the actual URL of the application if deployed to github pages.

Thanks for the comment, though it does not solve the issue. I tried in (clean) private mode, and the result is the same.
In fact, from my observation (see the other reply), it does not jump to IDP’s page, so nothing related to cookies so far.

It’s not usually seen as a good practice to have a dynamic redirect URL, as it being consistent is an important par of the OpenID authentication flow. Does the issue persist if you change calendar-orchestrator/app/src/pages/login.js at 827af71a597a18eb85e0432f2cbfd3e57c460c4f · renyuneyun/calendar-orchestrator · GitHub to be a static value?

If using a dynamic redirect URL is a hard requirement, I would advise using the URL constructor instead of string concatenation to be sure the result URL is correct, e.g. doing

useEffect(() => {
setBaseUrl(new URL(window.location.pathname, window.location.origin).href)
}, []);

instead of

useEffect(() => {
    setBaseUrl(window.location.origin + window.location.pathname);
  }, [setBaseUrl]);

Note that having setBaseUrl in the dependency array is unnecessary.

1 Like

Well, yes, it does persist.
The issue should be unrelated to the basrUrl, because the production build also correctly identifies it, both locally and on github pages. The 404 URL also changes accordingly (e.g. https://a.b.c/d/response_mode=query).

So, if “dynamic” means “a value that may change itself (several times) while using the application”, then no, it’s not required. This context’s main usage is to correctly identify where the application is running, which is fixed after application is loaded.

But if it means “anything not a hard-coded string”, then yes, it is required. Otherwise, local development will have to change its value and always take care not to commit it. Though, tbh, this is not critical.

Thanks for the tips. I’ll change the code accordingly. Though, issue is still there :melting_face:

Ok, I found something… between workaround and solution…

I need to downgrade next to 12.2.3 (maybe other 12.x.y could also work). After that, it works.

Weird… Hope to hear some ideas from experience people.