Next.jsとAuth.jsで認証機能を実装するチュートリアル

2024/09/13に公開

はじめに

Next.jsのバージョン14となり様々な機能を提供しています。

  • サーバーサイドレンダリング (SSR)
  • 静的サイト生成 (SSG)
  • APIルート
  • 画像最適化
  • ルーティングと動的ルーティング
  • ミドルウェア
  • Typescriptサポート

これらの機能はドキュメントを通してある程度理解可能ではありますが、実際にウェブアプリケーションを作って提供するとなるとこれらを組み合わせたりまたは周辺のライブラリを活用していく必要があります。

どのようなウェブアプリケーションを作っていくにしても必ず必要となってくるのが認証機能となります。

BtoCとなると必ずしも認証機能が必要でないというケースもあるかもしれませんが、サービス拡大にあたってはユーザー最適な機能の提供は必要不可欠となり、やはり認証機能が多かれ少なかれ必要になってくると思います。

今回はどんなウェブアプリケーションでも必要となってくる認証、アクセス制御をNext.jsを使ってどう実装していくのかコードベースでご紹介します。

これらの記事を通してNext.jsでは認証に必要なさまざまな機能を実装できることをイメージできるかと思います。

また記事は機能ごとに分けてご紹介していますので認証機能の中で自社で必要な機能だけをピックアップして参考にして頂くという使い方もいいかと思います。

完成イメージ

  • アカウント登録
    一般的なWebサービスを想定しており新たにアカウントをユーザー自身が発行します。
    メールアドレスと名前とパスワードを入力してアカウント登録を行います。
    この際、すでに登録されているメールアドレスで登録しようとするとエラーとなるよう制御を行なっています。

  • メールを確認しリンクをクリック
    アカウント登録が完了すると本人確認として登録したメールアドレス宛にメールが送られます。

  • メール認証処理
    届いたメールのリンクをクリックすることでサーバー側で本人確認を行うことができます。

  • ログイン
    登録したメールアドレスとパスワードを用いてログインを行います。

  • 設定画面にリダイレクト
    ユーザー設定画面というログイン済みのユーザーのみアクセス可能なページに遷移させます。

という一連の流れを実装していきます。

Image from Gyazo

  • アクセス制御
    このユーザー設定画面をログイン前のユーザーがアクセスした場合はログイン画面に強制的に遷移させます。

  • OAuth認証
    GitHubやGoogleなどの外部サービスを活用して認証を行うことも可能となっています。

GitHubの場合

Image from Gyazo

Googleの場合

Image from Gyazo

  • 二要素認証
    パスワードだけではセキュリティ的にというサービスの場合として二要素認証の実装も行っています。
    ログイン時にメールアドレス/パスワードを入力した後に、対象のメールアドレス宛に送られたワンタイムトークンを登録するとログインが可能となります。

Image from Gyazo

  • パスワードリセット
    ユーザーが登録したパスワードを忘れた場合のためにパスワードリセット機能を実装しています。

その①ユーザーがメールアドレスを入力するとパスワードリセットするための画面のリンクをメール送信します。(この動画ではリンクの遷移先が404となっていますが実装途中のためです。)

Image from Gyazo

その②メールにあるリンクをクリックすると、今回作成した画面が表示されるかと思います。パスワードを入力し「新しいパスワードを設定」ボタンをクリックすると「パスワードを更新しました。ログイン画面よりログインをお願いします。」というメッセージが表示されます。
ログイン画面から新しいパスワードでログインできることを確認します。

Image from Gyazo

システム構成

WIP

認証フローと画面の構成

認証の仕組みについて下記のような設計に基づき実装してあります。

メールアドレスとパスワードを使ってログインするというところまでは既にご存知かと思いますが、ログイン済み、未ログインの場合にそれぞれ画面へのアクセスがどこまでできるかという問題です。

最初の図は基本的なユーザーの利用の流れとなります。トップ画面に来たユーザーは、アカウント登録画面でアカウントを登録し、ログイン画面でログイン処理を行いログインできたら設定画面(一般的なウェブサイトでいうマイページの役割。今回はユーザー情報が表示される画面)に遷移します。

(設定画面については今回とは別の記事で作成していきます。)

Image from Gyazo

既にアカウントを登録済みの場合は、トップ画面からログイン画面に遷移しログイン処理を行います。

Image from Gyazo

設定画面はユーザー情報が表示される画面となり、未ログイン状態でアクセスされると困るのでアクセス拒否するよう設定します。

Image from Gyazo

またログイン済みのユーザーがアカウント登録画面やログイン画面にアクセスしても特にすることはないため、設定画面にリダイレクトするよう設定します。

Image from Gyazo

このようなイメージでログイン済み、未ログインの場合の画面アクセスを設定して行きます。

今回取り扱う技術スタック

  • Next.js
    Reactのフレームワークで、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)を簡単に実現できます。APIルートもサポートし、柔軟なデータ取得が可能です。

https://nextjs.org/

  • Tailwind CSS
    ユーティリティファーストのCSSフレームワークで、直感的にデザインを作成できます。事前定義されたクラスを使って、HTML内で簡単にスタイルを適用できます。

https://tailwindcss.com/

  • shadcn ui
    高度にカスタマイズ可能で、デザインに洗練されたコンポーネントを提供するReact UIライブラリです。Tailwind CSSとシームレスに統合できます。

https://ui.shadcn.com/

  • React Hook Form
    Reactアプリケーションでフォームを管理するためのライブラリで、パフォーマンスが良く、使いやすさを重視しています。簡単にフォームバリデーションを追加できます。

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

  • zod
    TypeScript向けの宣言的なスキーマバリデーションライブラリで、型安全にバリデーションを行えます。エラー処理も簡潔に書くことができます。

https://github.com/colinhacks/zod

  • Prisma
    TypeScript/JavaScriptのORM(Object Relational Mapping)ツールで、データベース操作を簡単にし、型安全で効率的にクエリを作成できます。

https://www.prisma.io/

  • Neon DB
    サーバーレスでスケーラブルなPostgreSQLデータベースサービスで、データベースのセットアップを簡単にし、ネイティブでサーバーレスアーキテクチャに最適化されています。

https://neon.tech/

  • Auth.js
    ユーザー認証を簡単に組み込めるライブラリで、OAuthやJWTを用いて、セッション管理を効率よく行えます。

https://authjs.dev/

  • Sendgrid
    メール送信サービスで、APIを介して大量のメールを簡単に送信できます。特にマーケティングやトランザクションメールに強いです。

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

実装の流れと記事のご紹介

上から順に実装していくことで完成イメージと同じアプリケーションを実現できます。

Next.jsの基本的な機能は知っている、またはこの技術スタックの使い方だけ知りたいなど具体的な課題を持っている方は該当する記事だけ参考にするというやり方もアリかと思います。

実際のコードだけでなく実装方針なども記載していますので参考になる部分は多いかと思います。

Next.jsのトップ画面をTailwind CSSとshadcnで素早く作る

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

アカウントの登録画面をNext.js/Tailwindcss/shadcnで作る

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

React Hook Formを活用して登録画面に入力フォームとバリデーションを設定する

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

Next.jsのサーバーアクションに登録フォームで入力したデータを渡す

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

Next.jsのサーバーアクションを活用してDBにアカウント情報を登録する

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

Next.jsのミドルウェアとAuth.jsを活用して画面のアクセス制御をする

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

Next.jsでログイン画面を作ってメールアドレス/パスワードでログインできるようにする

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

Next.jsでメール認証機能を実装する①メール送信機能

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

パスワードリセット処理を実装する①メール送信

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

Next.jsで二要素認証を実現し不正アクセスへの対応を実現する

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

Next.jsでGitHubとGoogleのOAuth認証を簡単実装する方法

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

この記事の対象読者

Next.jsで認証の仕組みの導入方法ついて集中的に取り上げており、次のような方を対象読者として想定しています。

  • React、TypeScriptを使用した開発に慣れている方
  • Next.js v13以降の実装パターン(App Router)を知っている方
  • Next.jsに認証の仕組みを導入する方法を学びたい方

Next.jsで認証の仕組みの導入方法ついて誌面を割くため、ReactやTypeScriptに関する解説は割愛しています。あらかじめご了承ください。

さいごに

Next.jsも近年、十分に商用サービスで活用できるだけの機能とエコシステムが整ってきているかと思います。

これらの記事を通してNext.jsでアプリケーションを自信を持って社内で提案またはお客様先で提案できることを切に願っています。

記事に関するお問い合わせ📝

記事の内容に関するご質問、ご意見などは、下記よりお気軽にお問い合わせください。
ご質問フォームへ

技術支援などお仕事に関するお問い合わせ📄

技術支援やお仕事のご依頼に関するお問い合わせは、下記よりお気軽にお問い合わせください。
お問い合わせフォームへ