Closed5
Next.js v13.1.0 以降で Basic 認証を設定する
このスクラップについて
Next.js で Basic 認証をかける方法を調べてたらそういえば過去のスクラップで同じようなことをやったなということを思い出した。
この時の苦労がこんな所で役に立つとは。
結論
必要なのは下記だけ。
コマンド
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"',
},
});
}
必要に応じてユーザー名やパスワードなどは環境変数から読み込む。
Next.js v13.1.0 からは直接レスポンスが返せる
それ以前のバージョンの場合は下記の記事が参考になる。
Vercel 公式リポジトリ
ちなみに
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にクローズされました