🔑

Vercel にデプロイした docsify に middleware を使って BASIC 認証をかける

2024/01/02に公開
3

こちらの記事に大感謝!

https://zenn.dev/monicle/articles/vercel-plain-middleware-basic-auth

docsify への導入には少しアレンジが必要だったので備忘録です。

コード

middleware.js
const next = () => {
  const headers = new Headers();
  headers.set("x-middleware-next", "1");
  return new Response(null, {
    headers,
  });
};

export const config = {
  matcher: "/",
};

const USER_NAME = process.env.BASIC_AUTH_USER || "admin";
const PASSWORD = process.env.BASIC_AUTH_PASSWORD || "admin";

export default function middleware(request) {
  const authorizationHeader = request.headers.get("authorization");

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

    if (user === USER_NAME && password === PASSWORD) {
      return next();
    }
  }

  return new Response("Basic Auth required", {
    status: 401,
    headers: {
      "WWW-Authenticate": 'Basic realm="Secure Area"',
    },
  });
}

基本的に上記の記事で紹介されているコードと同じですが、1箇所だけ変更します。

- import { next } from "@vercel/edge";
+ const next = () => {
+   const headers = new Headers();
+   headers.set("x-middleware-next", "1");
+   return new Response(null, {
+     headers,
+   });
+ };

初期化コマンドの docsify init ./docs はディレクトリ( docs )を作成してその中に .nojekyllindex.html を作成するだけなので、 node_modules ディレクトリは作られません。
その状態で import { next } from "@vercel/edge"; としても読み込み先が存在しなくてエラーになってしまうので、代わりに読み込み先のコードを直に書き込んでやります(引数 init を受け取ることはないので大元のコードをさらに簡略化)。

書いた middleware.jsdocs ディレクトリの直下に入れましょう。

Vercel へのデプロイ上での各種設定

デプロイの Root Directory は docs を設定。

Vercel の設定画面から BASIC_AUTH_USERBASIC_AUTH_PASSWORD の環境変数を設定しておきます。

ここまでの設定がうまくいっていれば BASIC 認証が有効になります。

Discussion

Yut IshihYut Ishih

npm install @vercel/edgeという操作はvercel cliをローカル環境にインストールした後、ローカル環境で実行すればいいのでしょうか?

AWtnbAWtnb

docsifyに認証をかけるだけであれば、元記事に書いてある npm install @vercel/edge を実行する必要もありません(この記述が本文にありませんでしたね)。
docs フォルダの中に middleware.js を配置してvercelにデプロイするだけでOKですよ!

これは、vercelの公式リポジトリにあるソースコードから必要な部分をコピペしてきているだけです↓

- import { next } from "@vercel/edge";
+ const next = () => {
+   const headers = new Headers();
+   headers.set("x-middleware-next", "1");
+   return new Response(null, {
+     headers,
+   });
+ };
Yut IshihYut Ishih

ありがとうございます!すこしは、Vercelに慣れ親しんでおこうと、アカウント取得および非認証サイト作り:やってみました。GITリポジトリにSSGでつくったhtmlたちがあれば、正常にデプロイできることだけ確認しました。おっしゃるとおりにmiddleware.jsおいたら認証できました。