Reading list Switch to dark mode

    How to implement authentication in Nextjs with Magento 2 using NextAuth

    Updated 28 February 2024

    In this blog, we will discuss how to implement authentication in Nextjs with Magento 2 using the NextAuth credentials provider.

    When you need to add authentication to your next.js project, NextAuth is a wonderful option. It’s easy to see why, given its extensive provider support, which includes GitHub, Google, Facebook, Credentials, and more. It can help you set up your authentication in minutes!

    However, sometimes you might need to implement your own custom backend with an email/password login with an API server.

    To implement the backend, you can use the credentials provider. We are going to use the NextAuth credentials provider to authenticate Nextjs with Magento.

    we hope this will help you out if you’re in the same boat!

    Searching for an experienced
    Magento 2 Company ?
    Find out More

    Also, Magento 2 Headless Development services will allow you to gain access to the headless development architecture.

    Create your Project

    We recommend creating a new Next.js app using, which sets up everything automatically for you. To create a project, Open a command prompt or terminal window in the location where you wish to save your project and run the following command.

    npx create-next-app@latest
    # or
    yarn create next-app
    # or
    pnpm create next-app

    After the installation is complete:

    • Run npm run dev or yarn dev to start the development server on http://localhost:3000
    • Visit http://localhost:3000 to view your application and see the following.
    Screenshot-from-2022-04-09-17-09-55
    Welcome to NextJs

    Let’s Start Setting up the API

    Now let’s add the NextAuth package by running the below command.

    yarn add next-auth

    This time to add NEXTAUTH URL in our .env file. Add the following to your .env file.

    NEXTAUTH_URL=http://localhost:3000

    First, we need to set up the next-auth for the app. It’s a straightforward process and the instructions can be found here

    Why we are using Magento?

    Magento 2 CMS offers versatile features to build a dynamic and powerful e-store. This CMS enables you to build a robust and highly secured e-store.

    Magento CMS can create and manage multiple storefronts with one Admin Panel. Magento CMS supports multiple languages, multiple currencies, and multiple pricing.

    Moreover, you can create a headless storefront using the best available frameworks such as Magento 2 ReactJS or NextJS or GatsbyJS and many more.

    Now we have to set up pages/api/[..nextauth].js  in our project. This contains the NextAuth.js dynamic route handler.

    Add MAGENTO_URL in our .env file. Add the following to your .env file.

    MAGENTO_URL=http://mymageServer.com
    import NextAuth from "next-auth";
    import CredentialProvider from "next-auth/providers/credentials";
    
    export default NextAuth({
      providers: [
        CredentialProvider({
          async authorize(credentials) {
            const baseUrl = process.env.MAGENTO_URL;
            const response = await fetch(
              baseUrl + "/rest/V1/integration/customer/token",
              {
                method: "POST",
                body: JSON.stringify(credentials),
                headers: {
                  "Content-Type": "application/json",
                },
              }
            );
            const data = await response.json();
            // Returning token to set in session
            return {
                token: data,
              };
          },
        }),
      ],
      callbacks: {
        jwt: async ({ token, user }) => {
          user && (token.user = user);
          return token;
        },
        session: async ({ session, token }) => {
          session.user = token.user;  // Setting token in session
          return session;
        },
      },
      pages: {
        signIn: "/login", //Need to define custom login page (if using)
      },
    });

    All requests to /api/auth/* (signIncallbacksignOut, etc.) will automatically be handled by NextAuth.js.

    Further Reading:

    • See the options documentation for more details on how to configure providers, databases, and other options.
    • Read more about how to add authentication providers here.

    Let’s create your login page which in our case is pages/login.js will have a form submit handler that will use nextauth’s signIn() callback to control if a user is allowed to sign in.

    import { signIn } from 'next-auth/client'
    
    const handleLogin = () => {
        signIn('credentials',
          {
            email,
            password,
            // The page where you want to redirect to after a 
            // successful login
            callbackUrl: `${window.location.origin}/account_page` 
          }
        )
      }

    At this point, if you have entered the correct credentials and your API endpoint is working as you’d hope it to work, you should be able to log in just fine.

    But if there is any issue such as the server being down, invalid credentials, etc. you will be redirected to the default error page (like the image below).

    Screenshot-from-2022-04-09-17-35-45
    Error page

    Instead what I want is to redirect it to my custom login page and explain the situation in a bit more detail to the user. So here’s what we do, we can stop the redirection using the below code on the login page.

    const res = await signIn('credentials',
          {
            email,
            password,
            callbackUrl: `${window.location.origin}/account_page` 
            redirect: false,
          }
        )
    if (res?.error) handleError(res.error)
    if (res.url) router.push(res.url);

    How to get token from the session?

    using useSession()

    The NextAuth.js client library makes it easy to interact with sessions from React applications.

    We can get token from session using useSession()

    • Client Side: Yes
    • Server Side: No

    The useSession() React Hook in the NextAuth.js client is the easiest way to check if someone is signed in.

    Make sure that <SessionProvider> is added to pages/_app.js.

    import { useSession } from "next-auth/react"
    
    export default function Component() {
      const { data: session, status } = useSession()
    
      if (status === "authenticated") {
        return <p>Signed in user token {session.user.token}</p>
      }
    
      return <a href="/api/auth/signin">Sign in</a>
    }

    useSession() returns an object containing two values: data and status:

    • data: This can be three values: Session / undefined / null.
      • when the session hasn’t been fetched yet, data will undefined
      • in case it failed to retrieve the session, data will be null
      • in case of success, data will be Session.
    • status: enum mapping to three possible session states: "loading" | "authenticated" | "unauthenticated"

    Using getSession()

    • Client Side: Yes
    • Server Side: Yes

    NextAuth.js provides a getSession() method which can be called client or server-side to return a session.

    It calls /api/auth/session and returns a promise with a session object, or null if no session exists.

    Client Side Example

    async function myFunction() {
      const session = await getSession()
      /* ... */
    }

    Server Side Example

    import { getSession } from "next-auth/react"
    
    export default async (req, res) => {
      const session = await getSession({ req })
      /* ... */
      res.end()
    }

    Note: When calling getSession() server-side, you need to pass {req} or context object.

    For more detailed info:  visit here

    That’s all about the NextAuth. If you have any questions please comment below, and we will try to respond to you.

    You may also Hire Magento 2 Developers for Headless development on Nextjs with Magento 2

    Thanks 🙂

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home