A Smart Way to Update NextAuth.js JWT Token
19/02/2025 - Raúl Cano
How to update your NextAuth.js session data without forcing re-authentication or database queries
I’d like to start with the thanks and credits to toomus the GitHub buddy who actuallly figured out how to do it.
The problem
I’m using NextAuth.js for authentication, and the app has an onboarding flow where users can’t get out of it untill the onboarding is done.
By default after the user signs in for the first time his onboarding step is set to inital, and that’s being set by NextAuth.js as a JWT token.
While at the same time the middleware checks that so we are protecting other routes untill the onboarding is done.
I wasn’t able to figured out how to update the JWT. One idea was to logged out the user and sign him in again, after the mutation is done. That would work, but that would be a bit of a pain for the users.
Here is where toomus came to the rescue.
His approach was simple but smart.
The trick is to create a special credentials provider that only exists to update our session. It doesn’t actually authenticate anything - it just passes through whatever data we give it. Here’s what we need:
// auth.config.ts
providers: [
GitHub,
CredentialsProvider({
id: 'session-update',
credentials: {},
async authorize(credentials) {
return credentials?.user ? JSON.parse(credentials.user) : null
},
}),
],
Btw. We are using the T3 starter for next with react query and tRPC for the api calls.
Then in our component where we need to update the session (in my case, completing the onboarding):
const { mutate: completeOnboarding } = api.onboarding.completeOnboarding.useMutation({
onSuccess: async (updatedUser) => {
await signIn('session-update', {
redirect: false,
user: JSON.stringify({
...updatedUser,
onboardingStep: "COMPLETED"
})
})
router.replace("/explore")
}
})
But how
When you call signIn with our special ‘session-update’ provider, NextAuth.js:
- Takes our updated user data
- Passes it through the authorize function
- Updates the JWT token
- Updates the session
No database queries, no signing out and back in - just smooth session updates.
Final thoughts
This solution is so clean it makes me wonder why it’s not more widely known. Big thanks again to toomus for sharing this approach.
Let me know what you think about this approach!