next-auth: Can't use auth() to get values from jwt() callback in v5
Environment
next: 14.0.2 => 14.0.2
next-auth: ^5.0.0-beta.3 => 5.0.0-beta.3
react: ^18 => 18.2.0
Reproduction URL
https://github.com/Celsiusss/nextauth-demo
Describe the issue
In the documentation, it says that:
When using auth(), the session() callback is ignored. auth() will expose anything returned from the jwt() callback or if using a “database” strategy, from the User. This is because the session() callback was designed to protect you from exposing sensitive information to the client, but when using auth() you are always on the server.
I tried to test this, but could not get values from the jwt() callback to be returned by auth(). It seems like the opposite of what this text says is true. Values from the session() callback is being returned, instead of jwt(). Not quite sure what the intended behavior really is, but I would love to access encrypted token values using auth().
How to reproduce
I have tried to create a minimal example in the Github link.
Here I am using auth() in a server component and in a route handler, to demonstrate it in two different ways.
page.tsx shows it being used in a server component.
api/route.ts shows it being used in a route handler.
client.tsx client component for signing in and using the route handler
auth.ts registers an oidc provider and defines the jwt() callback.
Expected behavior
I expected to be able to use auth() to retrieve values from the jwt() callback in server side components.
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Reactions: 29
- Comments: 35 (6 by maintainers)
Thanks to everyone for their help. For some reason I had to add more type checks to make it work, in case anyone wants a fully working auth.config.ts example …
Just to emphasize this again: I personally do not only want the raw unencrypted token, but have a refreshed one. In other words: I’m looking for a method to get the content of the
jwt()callback including a Set-Cookie header in case thejwt()content changed (e.g. refresh token rotation occured). Something likeunstable_getServerSession(), but for thejwt()content instead ofsession()If I understand the documentation correctly,
getToken()does indeed get the raw token, but it’s the token from the cookie, which is potentially stalewhats is resolver ? 🚩
I managed to get the getToken(…) to return the JWT with the following Route Handler:
Intentionally didn’t send in a salt param, typescript does not approve.
But as @czymstef mentions, with this the token is extracted from the cookie, which makes the token potentially stale.
— EDIT — Managed to get the JWT from a Server Action as well. This is from a Next.js app.
The documentation has changed. The bit that I originally quoted is now gone. (b5d5f20)
The commit references another issue (#9329) that was created after this describing the same problem.
Quoting a comment by @balazsorban44 made on that issue:
https://github.com/nextauthjs/next-auth/issues/9329#issuecomment-1909255054
Seems like
auth()will only use thesession()callback. A new way of suingauth()withAuthDatais in the works, and may solve this.Would have appreciated some better communication seeing as this issue has gathered a lot of traction, but at the same time many people commenting here is not even commenting about the original issue that I described, so I can see due to the discussions that emerged here it may not be clear what this issue really was about.
For me that’s not true I doesn’t have the
jwtproperties in mysessionobjectIs any of you guys by any chance using the drizzle-adapter and have the extended session object working?
Just ran into this as well after upgrading from a previous beta version. This is a pretty critical bug.
@vineetkia You might find this page helpful buried deep within the docs - Module Augmentation. Essentially you declare a module for ‘next-auth’ (or any other module you might want to override and then redeclare the interface’s with new properties, and then anywhere in your code that you use somethign that has Session, it will have all the new properties you are planning to include, so you don’t have to fight typescript.
It will merge in new properties. If you want to modify a nested object within you need to tweak slightly:
You can just inport
DefaultSessionfrom the next-auth library.You can also augment the type declaration to get rid of the type error in a cleaner way.
Just as a note, the type error with using token in the session callback is due to the typing where it will either have a token (if using jwt) or a user (if using a database); you can get around the type error somewhat by using the in operator narrowing:
If you need more info from the OIDC provider you can always get it by modifying the session object through the
jwtandsessioncallback. Just get whatever you need from theaccountparameter that gets passed to thejwtcallback, then that object gets passed down tosessionand whatever you return from that you can get throughauth. I do it in my app:You can then use module augmentation to get type completion.
There is v4’s getToken, though now that I think of it I am not entirely sure if that does execute
session; you might be right.And as per your second point, yes you are right one should not rely on patching
sessionsince it might either break in the future or we might be leaking the token somewhere else. IMO there should be a way of getting the raw token server-side as we might need it, for examplet to authenticate with 3rd party APIs if necessary.So is there no way at the moment to get the raw token server-side? Seems pretty limiting
I also met the issue and figured out that the migration guide of this part was a little misleading. After tracing the source code, I found that the
authreturned byNextAuthwas just agetSessioncall with auth config. According to the documentation, both of the returned values ofauthandgetSessionareSessionandSessionis the return value ofsession()callback, so the return value ofauthis the return value ofsession()callback, not the return value ofjwt()callback. The return value ofjwt()callback will be encoded and set within server side cookie.If we want
authto contain the returned value ofjwt()callback, we can do this withinsession()callback.