Closed5

Next.js v13.1.0 以降で Basic 認証を設定する

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

結論

必要なのは下記だけ。

コマンド
touch pages/middleware.ts
pages/middleware.ts
import { NextRequest, NextResponse } from "next/server";

export const config = {
  matchers: ["/", "/index"],
};

export function middleware(req: NextRequest) {
  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 === "4dmin" && pwd === "testpwd123") {
      return NextResponse.next();
    }
  }

  return new NextResponse("Auth Required.", {
    status: 401,
    headers: {
      "WWW-authenticate": 'Basic realm="Secure Area"',
    },
  });
}

必要に応じてユーザー名やパスワードなどは環境変数から読み込む。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ちなみに

Cloudflare Pages で Next.js のミドルウェアを使おうとすると不具合が出たので Cloudflare Pages のミドルウェアを使う必要がある。

詳細は省くがこんな感じ。

functions/_middleware.ts
interface ENV {
  BASIC_AUTH_IS_ENABLED: string;
  BASIC_AUTH_USERNAME: string;
  BASIC_AUTH_PASSWORD: string;
}

export const onRequest: PagesFunction<ENV> = async (context) => {
  if (context.env.BASIC_AUTH_IS_ENABLED !== "1") {
    return await context.next();
  }

  const authorizationHeader = context.request.headers.get("Authorization");

  if (authorizationHeader) {
    const authValue = authorizationHeader.split(" ")[1];
    const [user, password] = atob(authValue).split(":");

    if (
      user === context.env.BASIC_AUTH_USERNAME &&
      password === context.env.BASIC_AUTH_PASSWORD
    ) {
      return await context.next();
    }
  }

  return new Response("Auth Required.", {
    status: 401,
    headers: {
      "WWW-authenticate": 'Basic realm="Secure Area"',
    },
  });
};
このスクラップは2023/05/01にクローズされました