clerk / javascript

Official Javascript repository for Clerk authentication
https://clerk.com
MIT License
955 stars 210 forks source link

Auth data is not present on serverside - NextJS App Router #1528

Closed SimonHylander closed 9 months ago

SimonHylander commented 11 months ago

Package + Version

Dependencies + versions

{
  "name": "app-router",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "build": "next build",
    "dev": "next dev",
    "lint": "next lint",
    "start": "next start"
  },
  "dependencies": {
    "@clerk/nextjs": "^4.23.1",
    "@clerk/themes": "^1.7.5",
    "@t3-oss/env-nextjs": "^0.3.1",
    "dotenv": "^16.3.1",
    "encoding": "^0.1.13",
    "next": "^13.4.12",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "superjson": "1.12.2",
    "svix": "^1.7.0",
    "zod": "^3.21.4"
  }
}

Browser/OS

node 18.16.1

Description

After logging in, all auth properties are null in the server component using the auth() function. Auth properties are present using a client component with useAuth(). If I try to log auth in the "afterAuth" middleware all properties are also null.

<SignedIn></SignedIn>

only works in client components.

demo project https://github.com/SimonHylander/next-app-router-clerk

dimkl commented 11 months ago

Hello @SimonHylander thank you for reporting this. I ran the example application and after sign-in 3 requests were executed to reload the components using RSC. Of the 3 requests, 2 are for the same component. The first 2 requests were executed without session data, but the 3rd was executing (2nd request for the 1 component) is executed with the session populated. Even though it's not optimal it seems that the demo works. I will take a better look at it and come back to you.

Screenshot 2023-08-03 at 13 27 07
clementprevot commented 10 months ago

Hi!

I have noticed the same behavior. I use const { userId } = auth() in a server side component (a layout in this case) and const { userId } = useAuth() in a client component (the page at the same level as the layout).

When I authenticate using a magic link, I get redirected to my page with __clerk_status=verified and a __clerk_created_session, but the log in the server side return a null userId while in the client component I do have my proper userId. What is even weirder is that hard-refreshing the page in the browser fixes everything and I have my userId in both the server and client component

BRKalow commented 9 months ago

Hi y'all! Using the provided reproduction I'm not able to see the issue. Immediately after login, I'm getting userId from auth() on the server. This is through an email link as well as other flows.

I'm going to close this, but if anyone is able provide clear reproduction steps we'd be happy to take another look.

ethansnow2012 commented 9 months ago

I also encounter this. getAuth() do return userId when I am on the localhost but not when I deployed it to vercel.

Indu-Chandana commented 8 months ago

Hi!

I have noticed the same behavior. I use const { userId } = auth() in a server side component (a layout in this case) and const { userId } = useAuth() in a client component (the page at the same level as the layout).

When I authenticate using a magic link, I get redirected to my page with __clerk_status=verified and a __clerk_created_session, but the log in the server side return a null userId while in the client component I do have my proper userId. What is even weirder is that hard-refreshing the page in the browser fixes everything and I have my userId in both the server and client component

I have similar issue

omelette-watin commented 7 months ago

i experience the same issue but after some debugging it seems to only affect Firefox. Brave, Safari and Chrome are working as expected.

In Firefox i got the following warning in the console Cookie “__client_uat” has been rejected for invalid domain. It doesn't appear on other browsers.

EDIT: this seems to only affect dev environment on localhost

santagar commented 7 months ago

I have same problem in production environment. Localhost always works fine. I am using following lines to check auth in API service and userId is always null on server side. My app also print user info in another client pages and there is OK.

const { userId } = auth(); if (!userId) { return new NextResponse("Unauthorized", { status: 401 }); }

eob commented 6 months ago

I'm also encountering this bug. Similar to @clementprevot, immediately after login I get a null auth state on the server-side but a non-null auth state on the client side.

This prevents redirecting to a "post-login" SSR page that performs a few required account-update activities before redirecting the user to their eventual destination

For me this problem:

jamierumbelow commented 6 months ago

I'm afraid I'm also seeing the same problem. Client side authenticates fine, server returns null for everything.

What's weird is that it's working on localhost so it's very difficult to debug. Perhaps it's something to do with Vercel's serverless functions?

jamierumbelow commented 6 months ago

Okay, I did some more debugging and managed to make it work by deleting the __client_uat cookie.

For whatever reason, this cookie wasn't being cleared or replaced correctly when I logged out. Its value was stuck at 0.

I'm still not sure why:

  1. The cookie wasn't reset when I logged out / in
  2. This caused this failure

On (2), my suspicion is that it was triggering an invalid JWT handshake, which would explain why I was seeing a standard-signed-out reason in my logs. (This is confirmed here).

wowjulian commented 6 months ago

Same issue with Firefox. @BRKalow could you reopen the issue? I believe it's reproducible with Firefox, not Chrome.

edgarlcs commented 5 months ago

I had the same issue when I was trying to fetch a POST request from a Server Component to a Route Handler. I could get the auth data in the server component using auth() or currentUser(), but it showed null on the route handler. Turns out doing this is a mistake and you should not be fetching route handlers from a server component as it says in this video by Vercel.

I guess is not a 'fix' but after changing my logic to the server component I can say the issue is fixed now.

edanphillip commented 5 months ago

i was having this same issue on chrome where where my middleware function kept redirecting to the sign-in even though i was authenticated in clerk. also debug mode showed that all auth fields were null. this was the case only in production and didnt happen while i was on localhost. i opened the prod deployment in chrome incognito mode and suprisingly this error was gone and everything worked fine. I stopped being redirected to sign-in even though im logged in. this hinted that the problem was cookies to do with cookies. So, i cleared my cookies for my production domain and then everything worked as originally intended.

tldr; clearing cookies fixed this same issue for me.

kellenproctor commented 3 months ago

Clearing the cookies in local development cleared the issue of seeing null returned for auth() and currentUser() in a server component.

weisisheng commented 3 months ago

Hmm, tried to clear cookies and same error results. Both in FFOX and chrome. @clerk/nextjs@4.29.3

LukaGiorgadze commented 2 months ago

I had the same error here's how I fixed it:

OS: Mac Browser: Chrome Clerk: @clerk/nextjs@4.29.9

How I got this error:

  1. Created production environment by cloning development environment;
  2. Tried to log in using Google Social login and did not work, it requires some configuration (but cookies are kept in my browser);
  3. Configured Google auth, and when I tried to log in, I was experiencing the same issue - auth did not work on server side.

How I fixed: I just removed cookies and all application data in my browser, including cache and it worked. Try this.

BinaryWizardX commented 1 month ago

Hi !

I am also having the same issue on my local development environment. It works fine on the client side components and return null in serverside components. I've tried clearing cookies and cache data but the problem still exists. If somebody found any solutions to this issue please reply?

Thank you!

DoctorLimitless commented 1 month ago

why would you close this issue if its not solved?!!

weisisheng commented 4 weeks ago

Just to add to the discussion, I turned on my sync with server for time/data, cleared cookies, tried with VPN on and off, set firefox to accept cookies from session locally (0.0.0.0:3000 localhost:3000), still get the cookie “__client_uat” = 0 error.

Ubuntu 24.04, @clerk/clerk-js@5.5.3, @clerk/nextjs@5.1.3, node v20.11.0, nextjs@14.23.0

rlking1985 commented 3 weeks ago

Same issue, can't access auth() within an api route in next js.

GGalupo commented 3 weeks ago

Same issue here. Tried to clear cookies and switch browsers, but still have the problem.

ozair-dev commented 3 weeks ago

Same issue here. Works fine in localhost. But when hosted on vercel or any other hosting platform, the auth is not present on serverside (and user gets redirected to sign in page). But in clientside, I can see the signed in user with useAuth

@GGalupo , @rlking1985 , are you facing this issue in localhost? or only in hosted version? Also, are you using the clerk's API KEYS from the development instance or the production instance?

elnfar commented 2 weeks ago

I spent the whole day tryinna fixing it, it looks like if you are using route handler in app route. app/api/route.ts currentUser or auth() always returns back null. Instead, you can use server actions directly in Nextjs which seems to be working fine. Otherwise, you can still define and pass next in your middleware/ header and cookie.

QingjiaTsang commented 2 weeks ago

It works when getting userId out of auth() from CSC & SSC, as well as making requests from the client side to the API route handler where I use the auth function to get userId. I get the nullish value of userId, only when I run the fetch function from the SSC to the API route handler. I guess that's maybe because SSC loses the context of the clerk auth when making data fetching.

So make sure making the request from client component.

nandoviski commented 1 week ago

I'm having the same issue, I'm using NextJs 13 but using Pages, not the app directory, I'm also using tRpc, on the client side I'm logged in and can see the user, but in the server side, getAuth() (from "@clerk/nextjs/server") returns null for everything, I'm doing what they said in the docs, but nothing seems to help

I'd like to know if there's plans for this to be fixed or any work around? we are planning to migrate the authentication in our website, but with this bug would be impossible to recommend Clerk, can't even test it

elnfar commented 1 week ago

I found out that it's not only Clerk, Next-auth also does the same, please sure you are not sending the requet from SSC to api route directly, it should be from client component to api route, then it works. For just trying you can create a GET function in api/test/route.ts and get the user using auth(), it should work with GET in api route.

ozair-dev commented 1 week ago

but in the server side, useAuth returns null for everything

@nandoviski I don't think that useAuth is supposed to work in server side. You should use auth() on server side to get the authenticated user. Or maybe getAuth()

nandoviski commented 1 week ago

@ozair-dev sorry, I mean getAuth() from "@clerk/nextjs/server", I'll edit my post... I can't use auth() because I'm using Pages, not the app directory

nandoviski commented 1 week ago

@elnfar thanks, I tried but didn't work, I login in the website, and called the endpoint, but it returns null, maybe I'm doing something wrong, but I doing everything the say in the docs

Screenshot 2024-06-25 at 9 19 27 PM
elnfar commented 1 week ago

@elnfar thanks, I tried but didn't work, I login in the website, and called the endpoint, but it returns null, maybe I'm doing something wrong, but I doing everything the say in the docs Screenshot 2024-06-25 at 9 19 27 PM

Just, are you sure you are passing data back to server after the user is singed in or up? You can also log your request to see what to do you have there, and make sure you have clean config in middleware.ts for Clerk ( it changed after the update ).

nandoviski commented 1 week ago

@elnfar the middleware is what I got from the docs, export default clerkMiddleware(); and the config, I can log the request but I'm not sure what I need to have there... I'll see if I can find out... thanks again