clerk/javascript

`@clerk/nextjs` middleware redirection issue on login with email on chrome

shivanshubisht opened this issue ยท 16 comments

Preliminary Checks

Reproduction

https://github.com/shivanshubisht/clerk-next

Publishable key

pk_test_cmVuZXdlZC1raXRlLTU3LmNsZXJrLmFjY291bnRzLmRldiQ

Description

Steps to reproduce:

  1. Clone the repo and run cp .env.example .env.
  2. Update your environment variables and deploy it to vercel.
  3. Try logging in with email on Chrome in incognito directly via the preview deployment.

Expected behavior:
I should get redirected after logging in on Chrome

After logging in with email, clerk should automatically redirect to the redirect_url param which it doesn't on Chrome v124.0.6367.92 when deployed on vercel. However this works as expected on Safari in v17.2.1.

I am unsure if this is being caused by @clerk/nextjs sdk or next itself as it seems to be running fine locally when running it via pnpm.

Actual behavior:
You won't get redirected only for the first time until you do hard refresh on Chrome in incognito mode. This does not occur on Safari. Cookies are however getting created on both Chrome and Safari.

There is also an active thread on this on discord, but it doesn't seem to have any updates over there.

Environment

System:
    OS: macOS 14.2.1
    CPU: (16) arm64 Apple M3 Max
    Memory: 43.94 MB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.0.0 - /opt/homebrew/bin/node
    npm: 10.5.0 - /opt/homebrew/bin/npm
    pnpm: 9.0.6 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 124.0.6367.92
    Safari: 17.2.1
  npmPackages:
    @clerk/nextjs: ^5.0.3 => 5.0.3
    @types/node: ^20 => 20.12.7
    @types/react: ^18 => 18.3.1
    @types/react-dom: ^18 => 18.3.0
    eslint: ^8 => 8.57.0
    eslint-config-next: 14.2.3 => 14.2.3
    next: 14.2.3 => 14.2.3
    postcss: ^8 => 8.4.38
    react: ^18 => 18.3.1
    react-dom: ^18 => 18.3.1
    tailwindcss: ^3.4.1 => 3.4.3
    typescript: ^5 => 5.4.5

Thank you for the detailed report here - we're looking into this actively!

I noticed that the matchers used in the middleware are not quite correct. Could you try converting them to
'/account/login(.*)', format? (Docs: https://clerk.com/docs/references/nextjs/clerk-middleware), I'm hitting an error regarding the catch-all route based on this so please let me know if that fixes the issue or alters the behaviour you're seeing.

Thanks

We are experiencing similar issues to this. After completing MFA users are stuck on the sign-in route until refreshing the page.

We're also experiencing similar issues after upgrading clerk/nextjs and using the clerkMiddleware and SignIn components. Just wanted to bump this thread with some of our context!

We're using an email verification link method, and it seems like we get to a state where there ought to be a redirect, but no redirect occurs. If you manually refresh the page, you are authenticated and get redirected to the specified ?redirectUrl. This is identical to what is described in the discord issue here.

We noticed that during the handshake flow, there were two _client_uat cookies set, with different Domains. One was our domain prefixed with a . (.example.com), and the other without the prefixed . (example.com). It seems like these were out of sync at the end of the flow, where _client_uat for the prefixed cookie was set to 0, while the other was set to a value. Here's a screenshot of the dev console showing these two cookies when using ngrok.

image

After a refresh, we enter the authenticated state and there is a single _client_uat cookie available (the non-prefixed one).

I set up a new Clerk account and super-simple app to try to understand (and maybe figure out a workaround) for this issue. I did not see the issue until I switched the Clerk account from development to production. This does seem related to cookies.

  • On initial login, there are two __client_uat cookies and one of them has a 0 value.
  • The Clerk and containers in my top-level layout.tsx still think that the user is not signed in
  • Refreshing the page completes the sign in

Cookies after authenticating -- sign in is "stuck"

Screenshot 2024-05-01 at 9 21 20โ€ฏPM

Cookies after a page refresh -- everything looks good in the app

Screenshot 2024-05-01 at 9 27 13โ€ฏPM

My layout.tsx:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { ClerkProvider, SignInButton, SignedIn, SignedOut, UserButton } from '@clerk/nextjs'


const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body className={inter.className}>
          <div>
            <SignedOut>
              <SignInButton />
            </SignedOut>
            <SignedIn>
              <UserButton />
            </SignedIn>
          </div>
          {children}
        </body>
      </html>
    </ClerkProvider>
  );
}

package versions

  "dependencies": {
    "@clerk/nextjs": "^5.0.5",
    "next": "14.2.3",
    "react": "^18",
    "react-dom": "^18"
  },

Same issue here. Same setup as OP. Can be reproduced with your clerk starter repositories.

@desiprisg: correcting the matchers in the middleware does not fix the issue.

Some more details:

  • works on Safari, but not chrome
  • Roy on Discord mentioned, that it's not related to core 2 of clerk. However it seems to be just that. Using a minimal reproduction example and changing to clerk 4.29, everything works fine. Updating to clerk 5, this issue appears. (no matter if one uses the new middleware or the old authMiddleware)
  • on localhost, everything works fine. (could this be related to some nextjs caching issues, as dev builds don't cache that much? )
  • I also see this cookie behaviour @kwindla experiences, thought it's worth to mention

@desiprisg I updated the matchers and bumped up Clerk to v5.0.5 in the repro, but it still doesn't redirect on Chrome until you do a hard refresh.

Hey everyone, thanks so much for the detailed reproductions and information. We're looking at this internally and hope to have a solve this week.

I'm on the latest NextJS, Clerk, React, Node 20+ (as of today) ...

  • I'm experiencing the issue in Chrome (preview deployment to Vercel)
  • I'm not experiencing the issue in Chrome (on localhost)

Other Observations:

I have a standard client side form that uses a server action to insert a record into the database. After the insert, the server action redirects to the details page eg. "/pet/123456789".

On the redirect, if I console.log(params.id) in page.tsx, I would expect to see "123456789" but instead is comes through as "123456789.action" !?!

If I "hard browse" to "/pet/123456789" everything behaves as expected and console.log(params.id) in page.tsx outputs "123456789".

I'm not sure if this is a Clerk middleware issue as well, or something on the NextJS side ?

Note:

  • I'm experiencing the issue above in Chrome (preview deployment to Vercel)
  • I'm not experiencing the issue above in Chrome (on localhost)

I'm experiencing this same issue, and I noticed that in the middleware the cookie __session is set correctly but auth().getToken()returns null.

Sorry to be this guy, but can we get an update on this one please?

This issue basically breaks clerk for each and everyone on vercel, one of your suggested hosting providers. It's reproducible with your very own starter templates and SignIn component. It's not an Edge case, it happens for anyone following your docs.

If the fix is more complex, please propose a workaround for the time being.

This issue is reported for more than 2 weeks now (according to several discord posts) - having the very core of your application in a broken state - the auth component - for that long is really unfortunate.

Again I apologise for the impatience here.

Hello everyone - apologies for the delay here. We do have a fix in place that we will deploy within the day after validating that everything is in order and we'll be able to post more details about the original issue then.

Thank you!

A new version released v5.0.7 seems to have fixed the issue ๐ŸŽ‰

Yea looks like the latest release has fixed the issue ๐Ÿ‘Œ

Hey folks, thanks for the fix. :party

Just one minor comment: The authMiddleware is still broken in the same way. It's not a problem for me as migration to clerkMiddleware is anyhow preferred, but I guess as authMiddleware is still usable, it might be either a documentation thing or getting rid of authMiddleware?

Reproduction steps are:

  • Use the reproduction steps as described in this issue here
  • Use the authMiddleware instead of clerkMiddleware
import { authMiddleware } from "@clerk/nextjs/server";

export default authMiddleware({});

export const config = {
  matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};

But once again, thank you very much for the fix for clerkMiddleware. This was the main blocker anyhow.

@andnig thanks for the report, we'll look at this early next week!