レビュー済み·難易度: 中級·更新: 2026-04-16

Next.js Middleware で未認証ユーザーをリダイレクトする

middleware.ts でリクエスト時に Cookie をチェックし、未認証ユーザーをログインページへリダイレクトするルート保護の実装例。

nextjsauthenticationrouting

対応バージョン

nextjs 15react 19

前提環境

Next.js App Router のルーティング基礎(layout.tsx / page.tsx)を理解していること

概要

middleware.ts をプロジェクトルートに置くと、ページレンダリング前にリクエストを横断的に処理できる。 Cookie の存在チェックで未認証ユーザーをログインページへリダイレクトし、保護ルートへのアクセスを制御する。

インストール

# 追加インストールは不要

middleware.ts の実装

// middleware.ts(プロジェクトルートに配置)
import { NextRequest, NextResponse } from "next/server";

const PROTECTED_PATHS = ["/dashboard", "/settings", "/profile"];
const LOGIN_PATH = "/login";

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  // 保護対象パスかどうか確認
  const isProtected = PROTECTED_PATHS.some((path) => pathname.startsWith(path));
  if (!isProtected) return NextResponse.next();

  // Cookie でセッションの有無を確認
  const sessionToken = request.cookies.get("session-token");
  if (sessionToken) return NextResponse.next();

  // 未認証 → ログインページへリダイレクト(元 URL をクエリに付与)
  const loginUrl = new URL(LOGIN_PATH, request.url);
  loginUrl.searchParams.set("redirect", pathname);
  return NextResponse.redirect(loginUrl);
}

export const config = {
  matcher: [
    /*
     * 以下を除くすべてのパスにマッチする:
     * - _next/static(静的ファイル)
     * - _next/image(画像最適化)
     * - favicon.ico
     * - API ルート(/api/)
     */
    "/((?!_next/static|_next/image|favicon.ico|api/).*)",
  ],
};

ログイン後のリダイレクト先処理(オプション)

// app/login/page.tsx
import { redirect } from "next/navigation";

type Props = {
  searchParams: Promise<{ redirect?: string }>;
};

export default async function LoginPage({ searchParams }: Props) {
  const { redirect: redirectTo } = await searchParams;

  async function handleLogin(formData: FormData) {
    "use server";
    // ... 認証処理 ...
    // 成功時は元のページへ戻す
    redirect(redirectTo ?? "/dashboard");
  }

  return (
    <form action={handleLogin} className="space-y-4 max-w-sm mx-auto mt-16">
      <input name="email" type="email" placeholder="メールアドレス" className="w-full rounded border px-3 py-2 text-sm" />
      <input name="password" type="password" placeholder="パスワード" className="w-full rounded border px-3 py-2 text-sm" />
      <button type="submit" className="w-full rounded bg-blue-600 px-4 py-2 text-sm text-white">
        ログイン
      </button>
    </form>
  );
}

ポイント

  • middleware.ts はプロジェクトルート(src/ を使っている場合は src/middleware.ts)に配置する
  • config.matcher で Middleware を適用するパスを絞ると不要なリクエストへの処理を避けられる
  • request.cookies.get() で Cookie を読み取れる。Edge Runtime で動作するため node:crypto などの Node.js 専用 API は使えない
  • 実際の JWT 署名検証が必要な場合は Edge 対応ライブラリ(jose など)を使う。本サンプルは Cookie 存在チェックによるルート保護の構造を示す
  • リダイレクト先の redirect クエリを保持することで、ログイン後に元ページへ戻る UX が実現できる

注意点

Middleware は Edge Runtime で動作するため、Node.js の crypto モジュールなど一部の API は使えない。実際の JWT 署名検証が必要な場合は Edge 対応の jose ライブラリを使うこと。本サンプルは Cookie の存在チェックによるルート保護の構造を示す。

関連サンプル