こもるーとたぬきの備忘録

profile

【Next.js】Next.jsでBasic認証を実装してみた話

開発環境のみ、Basic認証を実装した。
Next.jsでは初めて実装したので、実装した方法をまとめる。

開発環境

デプロイ先→vercel

開発環境バージョン
Next.js15.1.2
TypeScript5.0.0
sass1.83.0

Basic認証のサンプル

Vercel社の公式サンプル集Basic認証のサンプルがある。
このサンプルはpage routerを使用している。
Next.js15ではapp routerのため、Next.js v14 の App Router で Basic 認証するにはを参考にしながら実装した。

src/app/api/auth/route.ts


    export const GET = () => {
        return new Response(
        // クライアントに表示される本文
        "Basic認証が必要です", 
        {
        // ステータスコード、認証が必要
        status: 401,
        // ヘッダー 
        headers: {
            // 認証を要求
            "WWW-Authenticate":
            'Basic realm="Access to the staging site", charset="UTF-8"',
        },
        });
    };  
    

src/middleware.ts


    import { NextRequest, NextResponse } from "next/server";

    export default function middleware(req: NextRequest) {
        // 環境変数を使用して、本番環境か否かを判別。本番→認証なし
        if (process.env.ENV_PREVIEW === "false") {
        return NextResponse.next();
        }

        // クライアント側から送信された認証情報とURLオブジェクトの取得
        const basicAuth = req.headers.get("authorization");
        const url = req.nextUrl;

        // 認証情報の有無を確認
        if (basicAuth) {
        // 認証情報を取得
        const authValue = basicAuth.split(" ")[1];
        const [user, pwd] = atob(authValue).split(":");

        // 認証情報のチェック
        if (
            user === process.env.BASIC_AUTH_USER &&
            pwd === process.env.BASIC_AUTH_PASSWORD
        ) {
            // 認証できたらページ表示
            return NextResponse.next();
        }
        }

        url.pathname = "/api/auth";
        // クライアント側に認証情報を求める
        return NextResponse.rewrite(url);
    }
    

middleware

middleware.ts/jsで実装したコードはリクエストが完了する前に実行することができる。
今回実装のような認証はもちろん、サーバー側へのリダイレクト、パスの書き換え、ボット検出などといった場合に使用することができるルーティング機能。

Basic認証では、盗聴のリスクがあることとはいえ、本番環境とほぼほぼ同じ開発環境なので、とりあえず気にしなくていいかな。
ひとまず実装ができてよかった。