[...nextauth].js 5.1 KB
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import axios from "axios";

/**
 * Reference:
 * https://next-auth.js.org/
 * https://strapi.io/blog/user-authentication-in-next-js-with-strapi
 * https://medium.com/@tom555my/strapi-next-js-email-password-authentication-a8207f72b446#id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjQwMmYzMDViNzA1ODEzMjlmZjI4OWI1YjNhNjcyODM4MDZlY2E4OTMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2NjE5NDM4MzEsImF1ZCI6IjIxNjI5NjAzNTgzNC1rMWs2cWUwNjBzMnRwMmEyamFtNGxqZGNtczAwc3R0Zy5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwMzU4MDUxNzI0MDg5MTg5NDI5OSIsImVtYWlsIjoiaGFyaXNoLnJrLnBhdGVsQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhenAiOiIyMTYyOTYwMzU4MzQtazFrNnFlMDYwczJ0cDJhMmphbTRsamRjbXMwMHN0dGcuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJuYW1lIjoiSGFyaXNoIFBhdGVsIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hLS9BRmRadWNxVlFSbE42TUQyeFJDVjhwMThlcXRSSjB0UmZpc2F1T21FeGVodFNnPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkhhcmlzaCIsImZhbWlseV9uYW1lIjoiUGF0ZWwiLCJpYXQiOjE2NjE5NDQxMzEsImV4cCI6MTY2MTk0NzczMSwianRpIjoiZDk1YzIyYzVkMjY1N2NmZWEwN2Q1M2QwMmZkMjY1NGVhMGE4NTA0OSJ9.F4xZZT2ebj3LvtOqFwC-EeneXUVzAEolss20Zz1JYpnWlfDmTAzJkStaXN_3n59X2jhppU2vLX426fihE1sjvfkbSFY3L--uMlGRjKbkKMzlhqppy2TUN1Qcsaqf8PSamLQxZx9Ta3qdmV4FCvf8FLXbiVmgX2KOYg3stitiL3vQpEDR2faAv-dlnaOSDbKU76elKf5VMVHGw9ed7dLeNF0qPRLXg_NrQ3dPBH1sDwfLh0g4elCMkneEtMjZY9ptLJxhc_bwuQpXs3xNwjlIAZA1gM60lhIiZESwlAnnpEBdIjPVsjoUeJEEM1bB8dP4hqndJPVwA80ZnqOOXiH8bQ
 */
export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    CredentialsProvider({
      name: "Sign in with Email",
      credentials: {
        email: { label: "Email", type: "text" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials, req) {
        /**
         * This function is used to define if the user is authenticated or not.
         * If authenticated, the function should return an object contains the user data.
         * If not, the function should return `null`.
         */
        if (credentials == null) return null;

        const { email, password } = credentials;

        // Check if email and password is specified.
        if (!email || !password) {
          throw new Error("Please enter email and password to login.");
        }

        /**
         * credentials is defined in the config above.
         * We can expect it contains two properties: `email` and `password`
         */
        try {
          const userResponse = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local`, {
            identifier: email,
            password: password
          });


          // console.log("Axios login returned with data:");
          console.log("userResponse", userResponse.data);
          // console.log(jwt);

          // Response from the above call can be
          // 1. Incase of a successful authentication.
          // {
          //     "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwiaWF0IjoxNjYxOTQzMzY1LCJleHAiOjE2NjQ1MzUzNjV9.kAN2ocQEqbjbR_-6-ogfZMplJIn1VHkCn3hoAW4QtmY",
          //     "user": {
          //         "id": 4,
          //         "username": "harish",
          //         "email": "harish@email.com",
          //         "provider": "local",
          //         "confirmed": true,
          //         "blocked": false,
          //         "createdAt": "2022-08-30T06:38:17.280Z",
          //         "updatedAt": "2022-08-31T10:03:59.430Z"
          //     }
          // }

          // 2. Incase of an invalid authentication.
          // {
          //     "data": null,
          //     "error": {
          //         "status": 400,
          //         "name": "ValidationError",
          //         "message": "Invalid identifier or password",
          //         "details": {}
          //     }
          // }

          return {
            ...userResponse.data.user,
            name: userResponse.data.user.email,
            jwt: userResponse.data.jwt,
            email: userResponse.data.user.email,
            user: userResponse.data.user
          };
        } catch (error) {
          console.log("Error while fetching credentials:");
          console.log(error.response.data);

          // Sign In Fail
          // return null;
          throw new Error("Invalid credentials");
        }
      }
    })
  ],
  secret: process.env.NEXTAUTH_SECRET,
  callbacks: {
    session: async ({ session, token }) => {
      // console.log("session 1", session);
      // console.log("session 2", token);
      session.id = token.id;
      session.jwt = token.jwt;

      // console.log("session callback invoked: ");
      // console.log(session);

      return Promise.resolve(session);
    },
    jwt: async ({ token, user }) => {
      // console.log("user 1", user);
      // console.log("token 1", token);

      const isSignIn = user ? true : false;
      if (isSignIn) {
        token.id = user.id;
        token.jwt = user.jwt;
      }

      // console.log("jwt callback invoked: ");
      // console.log(token);

      return Promise.resolve(token);
    }
  }
});