テクノロジー

Next.jsのunauthorized/forbiddenを使った認証・認可エラー処理

こんにちは、エンジニアの堤です。

最近はNext.jsを使った開発をしています。
Next.jsは多種多様な機能を提供しており、公式の機能で大抵のケースは対応できるのですが、それでも対応できないケースは生じてしまいます。
その中の一つとして認証・認可のエラー処理が挙げられます。そんな認証・認可のエラー処理が容易になるのが今後リリース予定のunauthorzed/forbiddenAPIです。本記事ではこれらの機能を試してみたいと思います。
※ これらは本稿執筆時点(Next.js 15.3.5)では実験的機能であり、以降の内容は正式リリースの際には変更になる可能性があります

既存のエラー処理

これまでNext.jsではnotFoundAPIが提供されており、所謂404エラーについてはnotFound関数とnot-found.tsxを用いて容易に対応することができました。
ただ、認証・認可エラー処理については機能が提供されておらず、自前で対応する必要がありました。unauthorized/forbiddenAPIを使えば認証・認可エラーを404エラーと似たように処理できるようになります。

事前準備

それでは早速unauthorized/forbiddenAPIを試していきたいところですが、前述した通り現時点では実験的機能であるため、以下のようにnext.config.tsexperimental.authInterrupts設定オプションを有効化する必要があります。

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  experimental: {
    authInterrupts: true
  }
};

export default nextConfig;

unauthorized

まずはunauthorizedから試してみます。とはいえ、notFoundを使ったことがある方ならほぼ同じ感覚で利用できます。

まず以下のようにapp/unauthorized.tsxを作成します。

// app/unauthorized.tsx
import Link from "next/link";

export default function UnauthorizedPage() {
  return (
    <main className="pt-10 text-center space-y-2">
      <h1>401</h1>
      <p>この画面にアクセスするにはログインしてください。</p>
      <Link href="/sign-in" className="border border-black rounded-xs p-1">
        ログイン画面へ
      </Link>
    </main>
  );
}

あとは、認証エラーとしたい箇所でunauthorized関数を呼び出すだけです。

// app/page.tsx
import { auth } from "@/auth";
import { unauthorized } from "next/navigation";

export default async function Dashboard() {
  const session = await auth();

  if (!session) {
    unauthorized();
  }

  return (
    <main className="space-y-2 pt-10 text-center">
      <h1>ダッシュボード</h1>
      <p>{session.user?.email}としてログインしています</p>
    </main>
  );
}

上記のように実装し、未ログインの状態で対象の画面にアクセスするとapp/unauthorized.tsxの内容が表示されます。

forbidden

続いてforbiddenを試してみます。といっても、unauthorizedと使い方はほぼ同じです。

以下のようにapp/forbidden.tsxを作成し

// app/forbidden.tsx
export default function ForbiddenPage() {
  return (
    <main className="pt-10 text-center space-y-2">
      <h1>403</h1>
      <p>この画面にアクセスする権限がありません。</p>
    </main>
  );
}

認可エラーとしたい箇所でforbidden関数を呼び出すだけです。

// app/admin/page.tsx
import { auth } from "@/auth";
import { forbidden, unauthorized } from "next/navigation";

export default async function AdminPage() {
  const session = await auth();

  if (!session) {
    unauthorized();
  }

  if (session.user?.role !== "admin") {
    forbidden();
  }

  return (
    <main className="space-y-2 pt-10 text-center">
      <h1>管理画面</h1>
      <p>{session.user?.email}としてログインしています</p>
    </main>
  );
}

上記のように実装し、権限のないユーザーで対象の画面にアクセスするとapp/forbidden.tsxの内容が表示されます。


いかがでしたでしょうか。
unauthorized/forbiddenAPIにより、これまで独自で実装する必要があった認証・認可エラーについて容易に対応することが可能となります。
まだ実験的機能のため本番環境で使うのは時期尚早ですが、正式にリリースされたら積極的に活用していきたいところです。

前の記事へ

次の記事へ

一覧へ戻る

「テクノロジー」カテゴリの最新記事

PAGE TOP