why doesn't next-auth jwt callback get called on page transitions?

Viewed 1333

I'm using next-auth Credentials provider to implement authentication in my next js application with a custom django backend.

Here is my jwt callback:

async jwt(token, user, account) {
    if (user && account) {
      // The user has just logged in.
      const decoded = jwt_decode(user.access)
      token.accessToken = user.access
      token.refreshToken = user.refresh
      token.accessTokenExpires = decoded.exp
      return token
    }
    if ((Date.now() + 15 * 1000) <= (token.accessTokenExpires * 1000)) {
      // The user has logged in before but the token.accessToken has not been expired.
      return token
    }
    // token.accessToken is expired and we need to get a new jwt using token.refreshToken.
    const newJwt = await refreshJwt(token.refreshToken)
    if (newJwt) {
      token.accessToken = newJwt
      const decoded = jwt_decode(newJwt)
      token.accessTokenExpires = decoded.exp
      return token
    }
    // token.accessToken and token.refreshToken are both expired.
    return {}
}

This is the problem:

After jwt(token.accessToken) expires, the jwt callback won't get called. So it cannot refresh the jwt(token.accessToken).

But when I refresh the page manually (hard refresh), it gets called and properly sets the new jwt(token.accessToken) using the token.refreshToken.

It also gets called and properly sets the new jwt when user changes tabs on his/her browser.

I want the jwt callback to get called every time I use the hook useSession. (I use useSession in all of my pages, both server-side rendered pages and statically-generated pages).

1 Answers

I fixed the problem by passing options to next-auth/client's Provider in _app.js:

return (
    <Provider session={session}
              options={{clientMaxAge: TIME_INTERVAL_IN_SECONDS_WHICH_HAS_TO_BE_LESS_THAN_JWT_EXPIRATION_TIME}} >
        ...
    </Provider>
)

for v4, the option is replaced by refetchInterval, so it should be as follow:

return (
    <SessionProvider session={session} refetchInterval={TIME_INTERVAL_IN_SECONDS_WHICH_HAS_TO_BE_LESS_THAN_JWT_EXPIRATION_TIME}>
        <Component {...pageProps} />
    </SessionProvider>
)
Related