authenticationnext.jsjwtnext-auth

next-auth: Updating session.user values after form submission without relogin in Next.js project


I have a Next.js project, and I use NextAuth for authentication. In the header, when a user is logged in, the user's first and last name are displayed, as shown in this code:

import { useSession } from "next-auth/react";
export default function Test() {
  const { data: session } = useSession();
  return (
    <div>
      <h2>{session.user.firstname}</h2>
      <h2>{session.user.lastname}</h2>
    </div>
  );
}

There is a section where the user can change and update their first and last name using a form. After submitting the form, the database is updated, but the values of session.user still reflect the old values unless the user logs out and logs in again.

[...nextauth].js file codes :

import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

const SECRET_KEY = process.env.JWT_SECRET_KEY;

export default NextAuth({
  providers: [
    CredentialsProvider({
      name: "credentials",
      async authorize(credentials) {
        // Connecting to the database and verify password
        //...
        const returnObject = {
          firstname: user.firstname,
          lastname: user.lastname,
          email: user.email,
        };
        return returnObject;
      },
    }),
  ],
  callbacks: {
    jwt: async ({ token, user }) => {
      user && (token.user = user);
      return token;
    },
    session: async ({ session, token }) => {
      session.user = token.user;
      return session;
    },
  },
  secret: SECRET_KEY,
  jwt: {
    secret: SECRET_KEY,
    encryption: true,
  },
  session: {
    jwt: true,
  },
  pages: {
    signIn: "/auth/login",
  },
});

How can I update the value of session.user without the need for the user to log in again so that the new values are displayed in the header section?


Solution

  • You can use the update(data?: any) method from the useSession() hook to update the session on the client-side without reloading the page:

    const { data: session, update } = useSession();
    

    Then, after updating the values in the database you can use this update method to update first and last name in the handle submit function:

     await update({ firstname, lastname });
    

    After that, you need to update the sesion on the server-side using the trigger: "update" option:

    async jwt({ token, trigger, session }) {
      if (trigger === 'update' && session?.firstname && session?.lastname) {
        token.firstname = session.firstname ;
        token.lastname = session.lastname;
      }
    
      return token
    }
    

    For more details, do not forget to go through the docs.