Implement Authentication in Next.js application using NextAuth.js

Implement Authentication in Next.js application using NextAuth.js

Sharing is caring!

247 Views -

NextAuth.js offers a powerful solution for implementing authentication in Next.js applications. In this blog post, we will explore how to integrate NextAuth.js into your Next.js application to establish a robust and user-friendly authentication system.

Understanding NextAuth.js

NextAuth.js is an open-source authentication package for Next.js apps. It simplifies the process of adding authentication to your app by providing a range of authentication providers, including OAuth, JWT, and database adapters. With NextAuth.js, you can handle authentication flows, token management, and user sessions with ease, allowing you to focus on building your application’s core features.

Setting Up Your Next.js Application

Before diving into the integration process, ensure you have a Next.js application ready to go. If you haven’t already, create a new Next.js project using your preferred setup

npm install next@latest react@latest react-dom@latest

I would prefer to install Next.js with a basic blog template

npx create-next-app@latest nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"

It will create a new directory called nextjs-blog.

cd nextjs-blog

Installation Next-auth package.

npm install next-auth

Configuration

I’m using Login authentication from Backend API.So Inside pages directory create directory api then inside api directory create auth directory.

Inside auth directory create file named as `[…nextauth].js`

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

export default NextAuth({
  providers: [
    CredentialsProvider({
      // The name to display on the sign in form (e.g. 'Sign in with...')
      name: 'my-project',
      // The credentials is used to generate a suitable form on the sign in page.
      // You can specify whatever fields you are expecting to be submitted.
      // e.g. domain, username, password, 2FA token, etc.
      // You can pass any HTML attribute to the <input> tag through the object.
      credentials: {
        email: {
          label: 'email',
          type: 'email',
          placeholder: 'jsmith@example.com',
        },
        password: { label: 'Password', type: 'password' }
      },
      async authorize(credentials, req) {
        const payload = {
          email: credentials.email,
          password: credentials.password,
        };

        const res = await fetch('API_URL/api/v1/auth/login', {
          method: 'POST',
          body: JSON.stringify(payload),
          headers: {
            'Content-Type': 'application/json',
          },
        });

        const user = await res.json();
        if (!res.ok) {
          throw new Error(user.message);
        }
        // If no error and we have user data, return it
        if (res.ok && user) {
          return user;
        }

        // Return null if user data could not be retrieved
        return null;
      },
    }),
    // ...add more providers here
  ],
  secret: process.env.JWT_SECRET,
  pages: {
    signIn: '/login',
  },
  callbacks: {
    async jwt({ token, user, account }) {
      if (account && user) {
        return {
          ...token,
          accessToken: user.token,
          refreshToken: user.refreshToken,
        };
      }

      return token;
    },

    async session({ session, token }) {
      session.user.accessToken = token.accessToken;
      session.user.refreshToken = token.refreshToken;
      session.user.accessTokenExpires = token.accessTokenExpires;

      return session;
    },
  },
  theme: {
    colorScheme: 'auto', // "auto" | "dark" | "light"
    brandColor: '', // Hex color code #33FF5D
    logo: '/logo.png', // Absolute URL to image
  },
  // Enable debug messages in the console if you are having problems
  debug: process.env.NODE_ENV === 'development',
});

Usage in Components

import { signIn, signOut, useSession } from 'next-auth/react';

function AuthButton() {
  const { data: session } = useSession();

  if (session) {
    return (
      <button onClick={() => signOut()}>Sign out</button>
    );
  } else {
    return (
      <button onClick={() => signIn('google')}>Sign in with Google</button>
    );
  }
}

Protecting Routes

import { getSession } from 'next-auth/react';

export async function getServerSideProps(context) {
  const session = await getSession(context);

  if (!session) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  // Continue with rendering the protected page
}

Run the following command to start your Next.js app’s “development server”

npm run dev

Conclusion

Implementing authentication in your Next.js application is a crucial step toward building a secure and user-friendly experience. NextAuth.js streamlines this process by providing a comprehensive authentication solution that integrates seamlessly with Next.js projects. Following the above-mentioned steps in this blog post, you can ensure that your application’s authentication system is robust, efficient, and tailored to your users’ needs. So go ahead and empower your Next.js app with NextAuth.js to take your user authentication to the next level.

You can check out the code on GitHub.

Reference:

Next-auth official package

Next.js official doc.

 

 

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments