Raul Cano logo

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:

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!