これは何?
自分用メモです。
Vercel で静的サイト(※Honkit ビルドなど)をホスティングする際に BASIC認証 および IPアドレス制限 を行う middleware.ts のスニペット。
↓ Honkit でビルドされた静的ファイル(html, css, ...)が
_book/ディレクトリに出力、静的サイトホスティングされる例。
導入
事前に @vercel/functions を package.json の dependencies への追加します。
npm install @vercel/functions
その後、下記の middleware.ts をプロジェクトルートに配置します。
middleware.ts
import { next } from "@vercel/functions";
export const config = {
matcher: "/(.*)",
};
export default function middleware(request: Request) {
// 許可IPアドレスチェック.
if (isAllowedIpAddress(request)) {
return next();
}
// BASIC認証.
if (isAuthorized(request)) {
return next();
}
return new Response("Basic Auth required", {
status: 401,
headers: {
"WWW-Authenticate": 'Basic realm="Secure Area"',
},
});
}
/**
* 許可IPアドレスチェック.
*
* @param {*} request
* @returns {boolean} true = 許可IPアドレス, false = 許可IPアドレスではない
*/
function isAllowedIpAddress(request: Request) {
// source IP address.
const ips = request.headers.get("x-forwarded-for") ?? "";
const ip = ips.split(",").pop(); // 偽装防止の為、末尾を.
// access denied when "x-forwarded-for" is invalid.
if (!ip) {
return false;
}
// access denied when "ALLOWED_IP_ADDRESSES" is empty.
if (!process.env.ALLOWED_IP_ADDRESSES) {
return false;
}
// load allowed IP addresses from environment variable.
const allowedIps = process.env.ALLOWED_IP_ADDRESSES.split(",").map((ip) => ip.trim());
return allowedIps.includes(ip);
}
/**
* BASIC認証.
*
* @param {*} request
* @returns {boolean} true = 認証OK, false = 認証NG
*/
function isAuthorized(request: Request) {
const authorizationHeader = request.headers.get("authorization");
if (!authorizationHeader) {
return false;
}
const basicAuth = authorizationHeader.split(" ")[1];
if (!basicAuth) {
return false;
}
const [user, password] = atob(basicAuth).toString().split(":");
const authorized =
user === process.env.BASIC_AUTH_USER && password === process.env.BASIC_AUTH_PASSWORD;
return authorized;
}
環境変数で、BASIC認証のID/Password、アクセス許可するIPアドレスを設定します。
-
ALLOWED_IP_ADDRESSES... comma separeted ip addresses -
BASIC_AUTH_USER... username -
BASIC_AUTH_PASSWORD... password

