Next.js Middlewareでのリダイレクト・書き換え・Cookie制御パターン
Next.js TypeScript Backend Frontend
結論
リダイレクトには redirect、内部転送には rewrite を使い、matcher で無限ループを防ぎます。
// Next.js公式仕様:middleware.ts の基本構成
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
const { pathname } = request.nextUrl;
// 1. 未認証ユーザーをログイン画面へリダイレクト
if (!token && pathname.startsWith('/dashboard')) {
const loginUrl = new URL('/login', request.url);
return NextResponse.redirect(loginUrl);
}
// 2. Cookieの更新レスポンス生成
const response = NextResponse.next();
response.cookies.set('last-visited', Date.now().toString(), { httpOnly: true });
return response;
}
// ⭕ 静的アセットと不要ルートを除外してパフォーマンス維持&ループ防止
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
Next.js公式仕様:NextResponse 3大機能の比較
| 機能 | 動作と結果 | 主なユースケース |
|---|---|---|
NextResponse.redirect(url) | ブラウザのアドレスバー表記を変更して遷移 | 認証ガード(ログインへ転送)、旧URLの移転 |
NextResponse.rewrite(url) | アドレスバー表記はそのままで内部パスを描画 | マルチテナント、A/Bテスト、APIプロキシ遮蔽 |
response.cookies.set() | レスポンスヘッダーの Set-Cookie を操作 | 認証トークンの付与、訪問履歴の更新 |
実際に起こる障害:TOO_MANY_REDIRECTS 無限ループ事故
Middlewareで未認証ガードを書く際、対象パスの判定が甘いと以下の無限ループ障害が発生します。
HTTP ERROR 310 (net::ERR_TOO_MANY_REDIRECTS)
発生原因と対策
未認証ユーザーが /dashboard にアクセスした際、/login へリダイレクトを掛けます。この時、/login 自身も Middleware の判定対象に含まれており、かつ「現在のパスが /login であるか」の除外チェックがないと、/login へのアクセスに対してさらに /login へのリダイレクトが連続発火してブラウザがクラッシュ します。
設定手順
- ルートディレクトリ直下(または
src/)にmiddleware.tsを配置する config.matcherを記述し、/_next/static,/_next/image,favicon.icoなどの静的ファイルを対象外にする- リダイレクト対象パスの判定時に
pathname === '/login'や/publicルートを除外条件に含める