Next.js Authentication: Secure Your App with NextAuth.js

Next.js Authentication: Secure Your App with NextAuth.js

Simplify User Authentication in Next.js Apps Using NextAuth.js

Authentication is a critical part of any web application, ensuring that only authorized users can access certain areas and functionalities. In this tutorial, we'll explore how to implement secure authentication in a Next.js application using NextAuth.js, a flexible and easy-to-use authentication library for Next.js.

Setting Up Your Next.js Project

Before we dive into authentication, let's setup a basic Next.js project. If you haven't already, install the Next.js CLI and create a new project:

npx create-next-app@latest my-nextjs-app
cd my-nextjs-app
npm install

Installing NextAuth.js

Next, install NextAuth.js and its required dependencies:

npm install next-auth

Configuring NextAuth.js

Create a new file called next-auth.js in the pages/api/auth directory. This file will configure NextAuth.js for your application:

// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.Google({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    // Add more providers here
  ],
  // Optional: Customize pages
  pages: {
    signIn: '/auth/signin',
    signOut: '/auth/signout',
    error: '/auth/error',
    verifyRequest: '/auth/verify-request',
    newUser: '/auth/new-user',
  },
  // Optional: Custom callbacks
  callbacks: {
    async signIn(user, account, profile) {
      return true;
    },
    async redirect(url, baseUrl) {
      return baseUrl;
    },
    async session(session, user) {
      session.userId = user.id;
      return session;
    },
    async jwt(token, user, account, profile, isNewUser) {
      return token;
    },
  },
});

Environment Variables

NextAuth.js requires environment variables for the authentication providers. Create a .env.local file in the root of your project and add the following:

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

Make sure to replace your-google-client-id and your-google-client-secret with your actual Google OAuth credentials. You can obtain these from the Google Developer Console.

Creating Authentication Pages

NextAuth.js provides default authentication pages, but you can customize them by creating your own. Create the following files in the pages/auth directory:

  • signin.js

  • signout.js

  • error.js

  • verify-request.js

  • new-user.js

Here's an example of a custom sign-in page:

// pages/auth/signin.js
import { providers, signIn, getSession, csrfToken } from 'next-auth/client';

export default function SignIn({ providers, csrfToken }) {
  return (
    <div>
      <h1>Sign In</h1>
      {Object.values(providers).map((provider) => (
        <div key={provider.name}>
          <button onClick={() => signIn(provider.id)}>
            Sign in with {provider.name}
          </button>
        </div>
      ))}
    </div>
  );
}

export async function getServerSideProps(context) {
  const { req } = context;
  const session = await getSession({ req });
  const providers = await providers();
  const csrfToken = await csrfToken(context);

  if (session) {
    return { redirect: { destination: '/' } };
  }

  return {
    props: { providers, csrfToken },
  };
}

Protecting Pages

To protect certain pages or routes, you can use the useSession hook provided by NextAuth.js. Here’s an example of how to protect a page:

// pages/protected.js
import { useSession, signIn } from 'next-auth/client';

export default function ProtectedPage() {
  const [session, loading] = useSession();

  if (loading) return <div>Loading...</div>;

  if (!session) {
    return (
      <div>
        <h1>You are not signed in</h1>
        <button onClick={() => signIn()}>Sign in</button>
      </div>
    );
  }

  return (
    <div>
      <h1>Welcome, {session.user.name}</h1>
    </div>
  );
}
Conclusion
In this tutorial, we've covered how to set up secure authentication in a Next.js application using NextAuth.js. We've seen how to configure authentication providers, create custom authentication pages, and protect routes. NextAuth.js makes it easy to implement robust authentication in your Next.js applications, allowing you to focus on building great features for your users.