Next-auth - How to update the session client side?

Viewed 4744

I manage to update my session serverside, with new user data, but event after assigning it to my session object in [...nextauth.js], my session client side remains the old one. It doesn't refresh, event if I use getSession().

This code works for the back-end :

callbacks.session = async function session({ session, token }) {
  // we can fetch info from back end here to add it to the session   
  session.user = token.user;
  session.jti = token.jti;

  // If user is logged, we refresh his session
  if (token?.user?.id) {
    const url = routes.api.entities.shop.get.byId.build(token?.user?.id);
    let apiResp = await axios.get(url, {});
    session.user = { ...apiResp.data };
    token.user = { ...apiResp.data };
  }

  return session;
};

How can I refresh the session in front-end ?

2 Answers

There is no easy official way to do it, it is still in discussion among contributors.

That said, there is a way. Next-auth does refresh session if you click on another tab, then on the one of your app. It happens, it is a javascript event we can reproduce.

So just define a method to do it :

const reloadSession = () => {
  const event = new Event("visibilitychange");
  document.dispatchEvent(event);
};

Call it, and .. you're done. Session did refresh.

reloadSession();

For more information, this behaviour comes from this part of the code

Using the hack of simulating a tab switch does not works anymore in the v4.

What you could do is to update the callback to session?update.

const createOptions = (req) => ({
  // ...
  callbacks: {
    async jwt({ token, ...params }) {
      if (req.url === "/api/auth/session?update") {
          const response = await fetch(`${process.env.NEXT_PUBLIC_URL}/api/users/get/${token.email}`);
          const newUser = await response.json();
          token.hasAcceptedTerms = newUser.hasAcceptedTerms;
      }
      return token;
    },
    async session({ session, token }) {
        if (session.user != null && token.hasAcceptedTerms != null) {
            session.user.hasAcceptedTerms = token?.hasAcceptedTerms;
        }

        return Promise.resolve(session);
     },
  },
});

export default async (req, res) => {
  return NextAuth(req, res, createOptions(req));
};

Then in your client you can do a call

  await axios.get('/api/auth/session?update');

Tribute goes to this answer on github.

Related