Tutorial for Implementing Authentication with Next.js and Auth.js

  • nextjs
    nextjs
  • authjs
    authjs
  • tailwindcss
    tailwindcss
  • shadcn
    shadcn
  • prisma
    prisma
  • postgresql
    postgresql
  • typescript
    typescript
  • vercel
    vercel
Published on 2024/09/13

Introduction

With the release of Next.js version 14, it now provides a wide range of features:

  • Server-side rendering (SSR)
  • Static site generation (SSG)
  • API routes
  • Image optimization
  • Routing and dynamic routing
  • Middleware
  • TypeScript support

You can get a basic understanding of these features through the documentation, but when it comes to actually building and delivering a web application, you need to combine them and also make use of surrounding libraries.

No matter what kind of web application you build, authentication is a feature you will almost always need.

In BtoC scenarios there may be cases where authentication is not strictly required, but as a service grows, providing features optimized for each user becomes essential, and in practice some form of authentication will be needed.

Here, we will walk through how to implement the authentication and access control that any web application needs, using Next.js and focusing on the actual code.

By going through these articles, you should be able to picture how to implement the various features required for authentication in Next.js.

Since the articles are split by feature, you can also just pick out and refer to the parts of the authentication system that your own product actually needs.

Final result image

  • Account registration
    We assume a typical web service where users create their own accounts.
    Users register an account by entering their email address, name, and password.
    At this time, we add logic so that trying to register with an email address that is already in use will result in an error.

  • Check email and click the link
    Once account registration is complete, a confirmation email is sent to the registered email address for identity verification.

  • Email verification process
    By clicking the link in the email, the server can perform identity verification.

  • Login
    Users log in using the registered email address and password.

  • Redirect to settings page
    After login, users are redirected to a user settings page that is only accessible to authenticated users.

We will implement this entire flow.

Image from Gyazo

  • Access control
    If a non-logged-in user tries to access the user settings page, they are forcibly redirected to the login page.

  • OAuth authentication
    It is also possible to authenticate using external services such as GitHub or Google.

For GitHub:

Image from Gyazo

For Google:

Image from Gyazo

  • Two-factor authentication
    For services where a password alone is not sufficient from a security standpoint, we also implement two-factor authentication.
    After entering the email address and password at login, users enter a one-time token sent to the corresponding email address to complete the login.

Image from Gyazo

  • Password reset
    We implement a password reset feature for cases where users forget the password they registered.

Step 1: When the user enters their email address, we send an email containing a link to the password reset page. (In this video, the link destination is 404 because it is still under implementation.)

Image from Gyazo

Step 2: When the user clicks the link in the email, the page we created this time should be displayed. After entering a new password and clicking the “Set new password” button, a message appears saying “Your password has been updated. Please log in from the login page.”
Then, confirm that you can log in with the new password from the login page.

Image from Gyazo

System architecture

WIP

Authentication flow and screen structure

The authentication mechanism is implemented based on the following design.

You are probably already familiar with logging in using an email address and password, but the question is how far users can access different pages depending on whether they are logged in or not.

The first diagram shows the basic flow of how a user uses the system. A user who arrives at the top page registers an account on the account registration page, performs the login process on the login page, and upon successful login is redirected to the settings page (which plays the role of a “My Page” in a typical website; in this case, it is a page that displays user information).

(The settings page will be created in a separate article from this one.)

Image from Gyazo

If the user has already registered an account, they go from the top page to the login page, perform the login process, and log in.

Image from Gyazo

The settings page displays user information, and it would be problematic if it were accessed while not logged in, so we configure it to deny access in that case.

Image from Gyazo

Also, if a logged-in user accesses the account registration page or login page, there is nothing in particular for them to do there, so we configure it to redirect them to the settings page.

Image from Gyazo

With this kind of image in mind, we configure page access for both logged-in and non-logged-in states.

Tech stack used in this tutorial

  • Next.js
    A React framework that makes it easy to implement server-side rendering (SSR) and static site generation (SSG). It also supports API routes, enabling flexible data fetching.

https://nextjs.org/

  • Tailwind CSS
    A utility-first CSS framework that lets you build designs intuitively. You can easily apply styles directly in HTML using predefined classes.

https://tailwindcss.com/

  • shadcn ui
    A React UI library that provides highly customizable and polished components. It integrates seamlessly with Tailwind CSS.

https://ui.shadcn.com/

  • React Hook Form
    A library for managing forms in React applications, focused on performance and ease of use. It allows you to add form validation easily.

https://react-hook-form.com/

  • zod
    A declarative schema validation library for TypeScript that enables type-safe validation. It also lets you write error handling in a concise way.

https://github.com/colinhacks/zod

  • Prisma
    An ORM (Object Relational Mapping) tool for TypeScript/JavaScript that simplifies database operations and lets you build type-safe and efficient queries.

https://www.prisma.io/

  • Neon DB
    A serverless, scalable PostgreSQL database service that simplifies database setup and is natively optimized for serverless architectures.

https://neon.tech/

  • Auth.js
    A library that makes it easy to integrate user authentication, efficiently handling session management using OAuth and JWT.

https://authjs.dev/

  • Sendgrid
    An email delivery service that lets you easily send large volumes of email via API. It is particularly strong in marketing and transactional emails.

https://sendgrid.kke.co.jp/

Implementation flow and article list

By implementing from top to bottom, you can build an application that matches the final result shown above.

If you already know the basic features of Next.js, or if you only want to learn how to use specific parts of this tech stack, you can just refer to the articles that match your concrete needs.

The articles cover not only the actual code but also implementation strategies, so there should be plenty of useful content.

Build the Next.js top page quickly with Tailwind CSS and shadcn

https://shinagawa-web.com/en/blogs/nextjs-tailwind-shadcn-homepage

Create an account registration page with Next.js/Tailwind CSS/shadcn

https://shinagawa-web.com/en/blogs/nextjs-tailwind-shadcn-account-registration-form

Use React Hook Form to add input fields and validation to the registration page

https://shinagawa-web.com/en/blogs/react-hook-form-validation-with-nextjs

Pass form input data to Next.js server actions

https://shinagawa-web.com/en/blogs/nextjs-server-actions-form-data

Use Next.js server actions to register account information in the DB

https://shinagawa-web.com/en/blogs/nextjs-server-actions-db-registration

Use Next.js middleware and Auth.js to implement page access control

https://shinagawa-web.com/en/blogs/nextjs-middleware-auth-access-control

Create a login page in Next.js and enable email/password login

https://shinagawa-web.com/en/blogs/nextjs-login-email-password

Implement email verification in Next.js (Part 1: Sending emails)

https://shinagawa-web.com/en/blogs/nextjs-email-verification-implementation-sending-email

Implement password reset (Part 1: Sending the email)

https://shinagawa-web.com/en/blogs/nextjs-password-reset-email-sending

Implement two-factor authentication in Next.js to protect against unauthorized access

https://shinagawa-web.com/en/blogs/nextjs-two-factor-authentication

Easily implement GitHub and Google OAuth authentication in Next.js

https://shinagawa-web.com/en/blogs/nextjs-github-google-oauth

Intended readers of this article

This article focuses specifically on how to introduce authentication into Next.js, and is intended for readers such as:

  • Those who are comfortable developing with React and TypeScript
  • Those who are familiar with implementation patterns in Next.js v13 and later (App Router)
  • Those who want to learn how to introduce authentication into Next.js

To devote space to explaining how to introduce authentication in Next.js, explanations of React and TypeScript themselves are omitted. Thank you for your understanding.

Conclusion

In recent years, Next.js has matured to the point where it has enough features and ecosystem support to be used in production services.

Through these articles, I sincerely hope that you will feel confident proposing applications built with Next.js, whether within your own company or to your clients.

Xでシェア
Facebookでシェア
LinkedInでシェア

Questions about this article 📝

If you have any questions or feedback about the content, please feel free to contact us.
Go to inquiry form