n9p4
n9p4

Reputation: 277

How to implement refresh token in Next.js using NextAuth?

I have implemented a simple authentication procedure using nextAuth, now I want to implement the refresh token procedure so the user can get e a new access token, the nextauth file provides documentation regarding implementation of refresh token using google, but I am currently using CredentialProvider nextAuth documentation about refresh token

[...nextauth].js file

export default NextAuth({
  providers: [
    CredentialProvider({
      name: "credentials",
      async authorize(credentials) {
        try {
          const user = await axios.post(
            `${process.env.API_URL}/auth/authentication/login`,
            {
              email: credentials.email,
              password: credentials.password,
            }
          );

          if (!user.data.user) {
            return null;
          }

          if (user.data.user) {
            return {
              id: user.data.user.id,
              name: user.data.user.name,
              surname: user.data.user.surname,
              email: user.data.user.email,
              role: user.data.user.role,
            };
          }
        } catch (error) {
          console.error(error);
        }
      },
    }),
  ],
  callbacks: {
    jwt: ({ token, user }) => {
      if (user) {
        token.id = user.id;
        token.name = user.name;
        token.surname = user.surname;
        token.email = user.email;
        token.role = user.role;
      }
      return token;
    },
    session: ({ session, token }) => {
      if (token) {
        session.id = token.id;
        session.name = token.name;
        session.surname = token.surname;
        session.email = token.email;
        session.role = token.role;
      }
      return session;
    },
  },
  secret: process.env.SECRET_KEY,
  jwt: {
    secret: process.env.SECRET_KEY,
    encryption: true,
    maxAge: 5 * 60 * 1000,
  },
  pages: {
    signIn: "/auth/login",
  },
});

Upvotes: 1

Views: 6180

Answers (1)

Mentlegen
Mentlegen

Reputation: 1238

With the credentials provider, the mechanics are the same to refresh a token. Here is your code with some example code added to it (see the comments). When you check for values in the jwt callback, that's where you can also check for its validity and call your endpoint for refresh.

export default NextAuth({
  providers: [
    CredentialProvider({
      name: "credentials",
      async authorize(credentials) {
        try {
          const user = await axios.post(
            `${process.env.API_URL}/auth/authentication/login`,
            {
              email: credentials.email,
              password: credentials.password,
            }
          );

          if (!user.data.user) {
            return null;
          }

          if (user.data.user) {
            return {
              id: user.data.user.id,
              name: user.data.user.name,
              surname: user.data.user.surname,
              email: user.data.user.email,
              role: user.data.user.role,
            };
          }
        } catch (error) {
          console.error(error);
        }
      },
    }),
  ],
  callbacks: {
    jwt: ({ token, user }) => {
      if (user) {
        token.id = user.id;
        token.name = user.name;
        token.surname = user.surname;
        token.email = user.email;
        token.role = user.role;
      }
      // Here, check the token validity date
      if (token.tokenExpiration < Date.now()) {
        // Call the endpoint where you handle the token refresh for a user
        const user = await axios.post(
            `${process.env.API_URL}/auth/authentication/refresh`,
            {
              refreshToken: token.refreshToken
            }
          );
        // Check for the result and update the data accordingly
        return {...token, ...user};
      }
      return token;
    },
    session: ({ session, token }) => {
      if (token) {
        session.id = token.id;
        session.name = token.name;
        session.surname = token.surname;
        session.email = token.email;
        session.role = token.role;
      }
      return session;
    },
  },
  secret: process.env.SECRET_KEY,
  jwt: {
    secret: process.env.SECRET_KEY,
    encryption: true,
    maxAge: 5 * 60 * 1000,
  },
  pages: {
    signIn: "/auth/login",
  },
});

Upvotes: 3

Related Questions