🔰はじめての方へ

VercelでHTMLサイトにBasic認証を設定する方法|無料!独自ドメインなしでもOK!Previewでは動くのに本番で効かない原因も解説

AI
記事内に広告が含まれています。
スポンサーリンク

Vercelに公開したHTMLサイトに、簡単なBasic認証をかけたいと思い、調べながら設定してみました。

VercelのBasic認証について検索すると、Next.jsやAstroなどのフレームワークを利用した方法は比較的多く見つかります。

一方で、

  • HTMLだけで作ったサイト
  • 独自ドメインを設定していない
  • 〇〇.vercel.app のURLをそのまま使っている
  • Vercel Authenticationではなく、自分でユーザー名・パスワードを設定したい
  • お金をかけたくない

というケースになると、情報が少なくなります。

実際に私も設定してみたところ、Preview環境ではBasic認証が動くのに、Production環境では認証がかからないという問題に遭遇しました。

最初は「独自ドメインを設定していないからでは?」と考えていましたが、原因はまったく別のところにありました。

最終的には、Productionドメインが古いDeploymentを指していたことが原因でした。

この記事では、HTMLだけのサイトにVercelのRouting Middlewareを利用してBasic認証を設定する方法から、Productionで反映されない場合の調査方法、vercel alias ls や vercel promote を使った解決方法までまとめます。

なお、Vercelは2025年以降、従来のEdge Middlewareから「Routing Middleware」へ移行しています。現在のVercel公式ドキュメントでも、middleware.ts をプロジェクトルートに置くRouting Middlewareが案内されています。

  1. HTMLだけのVercelサイトでもBasic認証はできる?
  2. 独自ドメインがなくてもBasic認証はかけられる
  3. 簡単な流れ紹介
  4. まずはVercelの環境変数を設定する
  5. HTMLサイトではpackage.jsonにtype moduleを追加する
  6. middleware.tsを作成する
    1. このコードで何をしているのか
  7. matcherの設定には注意する
  8. process.env に赤い線が出る場合
    1. まず@types/nodeをインストールする
    2. tsconfig.jsonが存在しない場合
    3. VS Codeに反映されない場合
    4. なぜHTMLサイトなのにNode.jsの型定義が必要なのか
    5. @vercel/functions は必要?
  9. HTMLサイト+Vercel Middlewareで実際に追加したファイル
  10. 設定したらProductionへデプロイする
  11. Previewでは動くのにProductionでは動かない?
  12. Middlewareが動いているかを確認する
    1. ここで確認する
  13. それでもブラウザでは古いサイトが表示された
  14. Vercelでは「Deployment」と「URL」を分けて考える
  15. vercel alias lsでURLの紐付けを確認する
  16. npx vercel project inspectでプロジェクトの紐付けも確認する
  17. vercel domains inspectが使えない場合もある
  18. 古いDeploymentを見ている場合はvercel promoteで解決できる
  19. npx vercel –prodとvercel promoteの違い
    1. npx vercel –prod
    2. npx vercel promote
  20. Vercel AuthenticationはOFFにしないといけない?
  21. Vercel AuthenticationをOFFにするリスク
  22. HobbyプランではProductionドメインとDeployment URLの扱いにも注意
  23. 今回のトラブルを解決するために試した手順
    1. STEP 1:Environment Variablesを確認
    2. STEP 2:Environment Variables変更後に再デプロイ
    3. STEP 3:Middleware自体が動くか確認
    4. STEP 4:Deploymentの固有URLを確認
    5. STEP 5:Production URLとの違いを比較
    6. STEP 6:aliasを確認
    7. STEP 7:正しいDeploymentをProductionへ昇格
    8. STEP 8:Production URLを再確認
  24. Vercel Basic認証で困ったときのチェックリスト
  25. まとめ

HTMLだけのVercelサイトでもBasic認証はできる?

結論から言うと、できます。

VercelのRouting Middlewareは、特定のフレームワーク専用の機能ではありません。

現在のVercel公式ドキュメントでも、Routing Middlewareは「any framework」で利用でき、プロジェクトのルートに middleware.ts を作成する方法が案内されています。

例えば、今回のようなシンプルなHTMLサイトなら、

project/
├── index.html
├── other.html
├── middleware.ts
├── package.json
└── ...

という構成で利用できます。

middleware.ts は package.json と同じ階層、つまりプロジェクトのルートに配置します。

そのため、

「Next.jsじゃないとMiddlewareは使えない」

というわけではありません。

独自ドメインがなくてもBasic認証はかけられる

今回、最初に私が疑ったのが、

独自ドメインを設定していないからBasic認証が使えないのでは?

という点でした。

しかし、これは原因ではありません。

Vercelには、

https://プロジェクト名.vercel.app

というVercel側が発行するURLがあります。

このURLでもProductionのサイトとして利用できます。

実際、今回も独自ドメインを設定していない vercel.app のURLにBasic認証を適用できました。

Vercel公式ドキュメントでも、Production Deploymentには生成されたDeployment URLが存在し、ProductionドメインへDeploymentを割り当てる仕組みが説明されています。

そのため、

「独自ドメインがないとVercelでBasic認証をかけられない」

と考える必要はありません。

ただし、後述するように、VercelのDeployment URLとProductionドメインがどのDeploymentを指しているかは非常に重要です。

簡単な流れ紹介

最短手順については下記記事をご参照ください。

【簡単】VercelでHTMLサイトにBasic認証を設定する最短手順|無料!独自ドメインなしでもOK!|maple@web
今回はシンプルなコードでVercelでBasic認証を設定するやり方をご紹介します。 VercelでのBasic認証を調べると無料でできるやり方があまり出てこなくて、でてきてもNext.jsのやり方だったりして自分には合っていないと思いまし…

ここでは詳しい内容を交えながら説明します。

まずはVercelの環境変数を設定する

Basic認証のユーザー名とパスワードをコードに直接書くのは避けます。

Vercelの「Environment Variables」を利用します。

(1)Vercelの該当するプロジェクトを開く

(2)左の検索窓に「Environment Variables」と入力

(3)右上の「Add Environment Variable」をクリック

下記入力欄が出てくる

(4)2つの環境変数を作る

・1つ目のKeyに「BASIC_AUTH_USER(名前はmiddleware.tsにかいてあるもの)」、Valueには任意のユーザー名を入れる

・「+ Add Another」をクリックして、2つ目のKeyに「BASIC_AUTH_PASSWORD(名前はmiddleware.tsにかいてあるもの)」、Valueには任意のパスワードを入れる

Vercelでは環境変数ごとに、

  • Production
  • Preview
  • Development

など、適用する環境を選択できます。

「Environments」で選ぶことができ、デフォルトでは上の「Sensitive」がONになっているため、「Production」か「Preview」しか選べない。

今回のようにPreviewとProductionの両方で動作確認したい場合は、少なくとも ProductionとPreviewの両方にチェックしておく。

(5)SAVE

Vercel公式でも、Productionの環境変数は次回のProduction Deploymentに適用され、vercel --prod でもProduction Deploymentを作成できると説明されています。

HTMLサイトではpackage.jsonにtype moduleを追加する

フレームワークを使っていない場合、ここも重要です。

package.json に、

{
  "type": "module"
}

を追加します。

例えば、

{
  "type": "module",
  "dependencies": {
    "@vercel/functions": "^3.0.0"
  }
}

のような形です。

Vercel公式のRouting Middleware APIでも、フレームワークを使っていない場合は package.json に "type": "module"を追加するか、JavaScriptファイルを .mjs にする必要があると説明されています。

今回のようなHTMLサイトでは、この設定を忘れないようにします。

middleware.tsを作成する

@vercel/functions はインストールしておきます。

npm install @vercel/functions

次に、プロジェクトのルートに、

middleware.ts

を作ります。

現在のVercelではRouting Middlewareが推奨されており、デフォルトのランタイムはEdgeです。必要に応じてNode.jsランタイムも指定できます。

Basic認証の例としては、以下のようにできます。

import { next } from "@vercel/functions";

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

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

  if (authorizationHeader) {
    const basicAuth = authorizationHeader.split(" ")[1];

    if (basicAuth) {
      const decoded = atob(basicAuth);
      const separator = decoded.indexOf(":");

      if (separator !== -1) {
        const user = decoded.slice(0, separator);
        const password = decoded.slice(separator + 1);

        if (
          user === process.env.BASIC_AUTH_USER &&
          password === process.env.BASIC_AUTH_PASSWORD
        ) {
          return next();
        }
      }
    }
  }

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

Vercel公式のRouting Middleware APIでも、@vercel/functions の next() を使ってMiddlewareの処理を次へ渡す方法が案内されています。

このコードで何をしているのか

まず、

const authorizationHeader = request.headers.get("authorization");

で、ブラウザから送られてきた Authorization ヘッダーを取得します。

Basic認証では、

Authorization: Basic XXXXXXXX

のような形式で認証情報が送信されます。

認証情報はBase64でエンコードされていますが、Base64は暗号化ではありません。HTTPSと組み合わせて利用することが重要です。

認証情報を取り出して、

const decoded = atob(basicAuth);

でデコードします。

その後、

const user = ...
const password = ...

としてユーザー名とパスワードを分離し、

process.env.BASIC_AUTH_USER
process.env.BASIC_AUTH_PASSWORD

と比較します。

一致すれば、

return next();

で通常のサイト処理へ進みます。

一致しない場合や認証情報が存在しない場合は、

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

を返します。

HTTPのBasic認証では、サーバーが 401 Unauthorized と WWW-Authenticate を返すことで、ブラウザが認証情報の入力を促します。

matcherの設定には注意する

今回のサンプルでは、

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

としています。

これはトップページ / に対してMiddlewareを実行する設定です。

例えば、

/

には認証がかかりますが、

/about.html
/shop.html

などにはそのままでは適用されません。

VercelのRouting Middlewareでは、matcher によってMiddlewareを実行するパスを指定できます。

サイト全体を保護したい場合は、対象パスを広げる必要があります。

例えば、

export const config = {
  matcher: "/((?!favicon.ico).*)",
};

などです。

ただし、サイト全体に適用する場合はCSS、JavaScript、画像などの静的ファイルへのリクエストも考慮する必要があります。

そのため、最初はトップページだけで動作確認し、問題なく動くことを確認してから対象範囲を広げるのがおすすめです。

process.env に赤い線が出る場合

ここまで設定すると、次にTypeScriptのエラーでつまずくことがあります。

私の場合、middleware.ts の以下の部分に赤い線が表示されました。

if (
  user === process.env.BASIC_AUTH_USER &&
  password === process.env.BASIC_AUTH_PASSWORD
) {
  return;
}

VS Codeには、

名前 'process' が見つかりません。
ノードの型定義をインストールする必要がありますか?

というエラーが表示されました。

一見すると、Vercelの環境変数が認識されていないようにも見えます。

しかし、今回の原因はVercelの環境変数ではなく、TypeScript側がNode.jsの型定義を認識していなかったことでした。

まず@types/nodeをインストールする

エラーメッセージにも表示されている通り、Node.jsの型定義をインストールします。

ターミナルで、

npm install -D @types/node

を実行します。

ただし、私の場合はこれだけでは赤い線が消えませんでした。

これやった場合、GitHub管理している人はとんでもない量をプッシュすることになるので、gitignoreに下記追記しましょう。

.vercel
node_modules

tsconfig.jsonが存在しない場合

ここで確認したいのが、プロジェクト内に tsconfig.json が存在するかどうかです。

今回のサイトはNext.jsなどのフレームワークを使用していない、シンプルなHTMLサイトだったため、もともと tsconfig.json がありませんでした。

そこで、プロジェクトのルートに新しく tsconfig.json を作成しました。

プロジェクト/
├── index.html
├── middleware.ts
├── package.json
├── node_modules/
└── tsconfig.json

tsconfig.json の中身は以下のようにしました。

{
  "compilerOptions": {
    "types": ["node"]
  }
}

これによって、TypeScriptにNode.jsの型定義を使用することを明示します。

VS Codeに反映されない場合

tsconfig.json を作成しても、すぐに赤い線が消えない場合があります。

その場合は、VS Codeで、

⌘ + Shift + P

を押して、

TypeScript: Restart TS Server

を実行します。

それでも改善しない場合は、VS Codeを一度再起動します。

今回はこちらの設定を行ったことで、

process.env.BASIC_AUTH_USER
process.env.BASIC_AUTH_PASSWORD

の process に表示されていた赤い線が消えました。

なぜHTMLサイトなのにNode.jsの型定義が必要なのか

今回のサイト自体はHTMLで作られています。

そのため、

HTMLサイトなのに、なぜNode.jsの設定が必要なの?

と疑問に思いました。

ここで重要なのは、HTMLそのものではなく、middleware.ts がTypeScriptで書かれていることです。

process.env は環境変数を取得するために使っている仕組みですが、TypeScriptから見ると process が何なのかを知るための型定義が必要になります。

つまり、

HTMLサイト
    ↓
middleware.tsを追加
    ↓
TypeScriptでMiddlewareを実行
    ↓
process.envを使用
    ↓
Node.jsの型定義が必要

という関係です。

今回のように、フレームワークを使っていないシンプルなHTMLサイトでは、tsconfig.json 自体が存在しないこともあります。

その場合は、@types/node をインストールするだけでなく、

{
  "compilerOptions": {
    "types": ["node"]
  }
}

を設定することで、TypeScriptのエラーを解消できます。

@vercel/functions は必要?

今回、最初に試したコードでは、

import { next } from "@vercel/functions";

としていました。

しかし、今回のシンプルなHTMLサイトでは、この next() を使用しなくてもMiddlewareを実装できました。

そのため最終的には、@vercel/functions のimportを削除し、認証成功時はMiddlewareの処理を終了するシンプルな形にしています。

最終的な middleware.ts は以下のようになりました。

export const config = {
  matcher: ["/", "/another.html"],
};

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

  if (authorizationHeader) {
    const basicAuth = authorizationHeader.split(" ")[1];

    if (basicAuth) {
      const decoded = atob(basicAuth);
      const separator = decoded.indexOf(":");

      if (separator !== -1) {
        const user = decoded.slice(0, separator);
        const password = decoded.slice(separator + 1);

        if (
          user === process.env.BASIC_AUTH_USER &&
          password === process.env.BASIC_AUTH_PASSWORD
        ) {
          return;
        }
      }
    }
  }

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

matcher に配列を指定することで、

/

と、

/another.html

の両方をBasic認証の対象にしています。

VercelのRouting Middlewareでは、matcher に複数のパスを指定できます。

HTMLサイト+Vercel Middlewareで実際に追加したファイル

今回の最終的な構成は、非常にシンプルです。

プロジェクト/
├── index.html
├── shoplist.html
├── middleware.ts
├── package.json
├── tsconfig.json
└── node_modules/

追加した主なものは、

ファイル役割
middleware.tsBasic認証を実行
tsconfig.jsonTypeScriptでNode.jsの型定義を利用
package.jsonNode.js型定義などの依存関係を管理

です。

HTML自体を書き換える必要はありません。

これが今回、個人的にかなり便利だと感じたところです。

既存のHTMLをほとんど変更せず、Vercel側のMiddlewareで特定ページにアクセス制限を追加できました。

設定したらProductionへデプロイする

環境変数をProductionに設定しただけでは、既存のDeploymentに自動的に反映されるわけではありません。

新しいProduction Deploymentを作成します。

Vercel CLIを利用している場合は、

npx vercel --prod

です。

Vercel公式でも、--prod オプションはProductionドメイン用のProduction Deploymentを作成するために利用できると説明されています。

ここまでで、

HTMLサイト
↓
middleware.ts
↓
Basic認証
↓
環境変数
↓
npx vercel --prod

という流れになります。

Previewでは動くのにProductionでは動かない?

ここからが、今回一番勉強になった部分です。

実際に設定してみたところ、

Preview
→ Basic認証が表示される

Production
→ Basic認証が表示されない

という状態になりました。

最初は、

  • 環境変数がProductionに設定されていない?
  • middleware.ts が動いていない?
  • vercel.app ドメインだから?
  • ブラウザキャッシュ?
  • Vercel Authenticationが邪魔している?

など、いろいろな可能性を考えました。

しかし、ここで重要なのは、

Basic認証のコードをいきなり修正しないことです。

まず、

「そもそもProductionでMiddlewareが実行されているのか?」

を確認します。

Middlewareが動いているかを確認する

Basic認証のコードを一旦すべて外し、テスト用に以下のようなMiddlewareにします。

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

export default function middleware(request: Request) {
  return new Response("Middleware is working", {
    status: 200,
  });
}

そして、

npx vercel --prod

でProductionへデプロイします。

Vercel公式のRouting MiddlewareのGetting Startedでも、Middlewareから直接文字列を返して、Middlewareが実行されているか確認する方法が紹介されています。

ここで確認する

Production URLを開いて、

Middleware is working

と表示されたら、

MiddlewareはProductionでも正常に動いています。

逆に通常の index.html が表示されるなら、Middlewareが実行されていない可能性があります。

この切り分けは非常に重要です。

それでもブラウザでは古いサイトが表示された

今回、ここでさらに不思議なことが起きました。

VercelのDeployment詳細画面を見ると、テスト用Middlewareを入れたDeploymentには、

Middleware is working

と表示される状態になっていました。

ところが、自分のブラウザでProduction URLを開くと、

元のindex.html

が表示されます。

シークレットモードでも同じでした。

ここで、

「Middlewareがデプロイされていない」

とは考えにくくなりました。

なぜなら、DeploymentそのものにはMiddlewareが存在しているからです。

そこで、次に調べるべきなのは、

自分がアクセスしているProduction URLが、どのDeploymentを指しているのか?

ということでした。

Vercelでは「Deployment」と「URL」を分けて考える

Vercelでは、Deploymentを作成すると、そのDeployment固有のURLが発行されます。

さらにProduction用のドメインやAliasが、特定のDeploymentを指します。

Vercelの公式ドキュメントでも、Production Deploymentには「Current」「Promoted」「Staged」などの状態があり、現在Productionのドメインから配信されているDeploymentが「Current」として扱われます。

つまり、

最新のDeploymentが存在する

ことと、

自分がアクセスしているProduction URLが
最新のDeploymentを見ている

ことは、必ずしも同じとは限りません。

今回まさにここで問題が起きていました。

vercel alias lsでURLの紐付けを確認する

そこで実行したのが、

npx vercel alias ls

です。

このコマンドでは、VercelのAliasがどのDeployment URLに紐付いているかを確認できます。

今回の調査では、実際のProduction URLが、

20日前の古いDeployment

を指していることが分かりました。

イメージとしては、

Production URL
      ↓
古いDeployment
      ↓
Basic認証なし

となっていた一方で、

最新Deployment
      ↓
Basic認証あり

という状態でした。

これなら、いくら最新DeploymentにBasic認証を追加しても、Production URLを開いたときに認証が表示されないのは当然です。

npx vercel project inspectでプロジェクトの紐付けも確認する

もう一つ確認に使えるコマンドが、

npx vercel project inspect

です。

これを実行すると、現在のディレクトリがどのVercel Projectに紐付いているのか確認できます。

例えば、

Found Project ...

と表示され、

Name
Root Directory
Framework Preset
Node.js Version

などを確認できます。

複数のVercelプロジェクトを管理している場合は、

「今ターミナルから操作しているフォルダが、本当に目的のVercel Projectを見ているか?」

を確認するためにも便利です。

vercel domains inspectが使えない場合もある

今回、

npx vercel domains inspect example.vercel.app

のような確認も試しました。

しかし、Vercelが発行している vercel.app のURLについては、

You don't have access to the domain ...

というエラーになりました。

これは「そのサイトが存在しない」という意味ではありません。

Vercelのドメイン管理上、自分で所有・管理する独自ドメインと、Vercelが提供する vercel.app のプロジェクトURLは扱いが異なるためです。

今回のようなケースでは、domains inspect に固執するよりも、

npx vercel alias ls

でAliasの紐付きを確認するほうが分かりやすいケースがあります。

古いDeploymentを見ている場合はvercel promoteで解決できる

今回、最終的に使ったのが、

npx vercel promote <最新DeploymentのURL>

です。

例えば、

npx vercel promote https://<最新DeploymentのURL>

のように実行します。

vercel promote は、既存のDeploymentを現在のProduction Deploymentとして昇格させるコマンドです。Vercel公式ドキュメントでも、既存DeploymentをCurrentとして扱うためのコマンドとして案内されています。

これによって、

Production URL
      ↓
最新Deployment
      ↓
middleware.ts
      ↓
Basic認証

という正しい状態に戻すことができました。

今回も、promote 実行後にProduction URLへアクセスすると、Basic認証が表示されるようになりました。

npx vercel –prodとvercel promoteの違い

ここは少し分かりにくかったので整理しておきます。

npx vercel –prod

npx vercel --prod

は、現在のコードからProduction Deploymentを作成するためのコマンドです。

Vercel公式ドキュメントでも、--prod はProduction用のDeploymentを作成するオプションとして説明されています。

npx vercel promote

npx vercel promote <deployment-url>

は、すでに存在するDeploymentをProductionとして現在の配信対象にするためのコマンドです。

そのため、

コードを変更した
↓
新しくProduction Deploymentを作る

なら、

npx vercel --prod

です。

一方、

このDeploymentは正しい
↓
でもProduction URLが別のDeploymentを見ている

という場合には、

npx vercel promote <deployment-url>

が役立ちます。

Vercel AuthenticationはOFFにしないといけない?

今回、もう一つ悩んだのがVercel Authenticationです。

AIに相談したところ、

Vercel AuthenticationをOFFにしないと、自分で実装したBasic認証が使えない

という案内を受けました。

しかし、これは最初から安易にOFFにするべきではありません。

Vercel Authenticationは、Vercel側でDeploymentへのアクセスを制御するための仕組みです。

一方、今回実装しているBasic認証は、

ブラウザ
↓
Vercel Routing Middleware
↓
ユーザー名・パスワードを確認
↓
HTMLサイト

というアプリケーション側の認証です。

つまり、そもそも別の仕組みです。

Vercel公式では、Vercel AuthenticationはDeployment Protectionの一部として提供されており、アクセスできるVercelユーザーを制限する仕組みだと説明されています。

また、現在のVercelではDeployment ProtectionがRouting Middlewareより前のアクセス制御として機能します。つまり、Vercel Authenticationが有効な環境では、そもそもRouting Middlewareまで到達する前にVercel側の認証が要求されるケースがあります。

そのため、

「Vercel AuthenticationをONにしたまま、一般ユーザーには自作Basic認証だけを見せたい」

という要件の場合は、VercelのDeployment Protectionの対象範囲を確認することが重要です。

Vercel AuthenticationをOFFにするリスク

Vercel AuthenticationをOFFにする操作は、単に「今回のBasic認証を動かすための設定変更」と考えないほうが安全です。

Vercel公式では、Vercel Authenticationを無効にすると、既存のDeploymentが保護されなくなると説明されています。

つまり、

Vercel Authentication OFF

にすることで、

今回のサイトだけではなく、設定しているDeploymentの保護状態にも影響する可能性があります。

そのため、

Basic認証を使いたいから、とりあえずVercel AuthenticationをOFF

という判断はおすすめしません。

まず、

  1. 現在のDeployment Protectionの設定を確認
  2. Production / Previewの保護範囲を確認
  3. 本当にOFFにする必要があるのか確認
  4. 必要な場合だけ変更する

という順番にするのが安全です。

HobbyプランではProductionドメインとDeployment URLの扱いにも注意

現在のVercelのDeployment Protectionでは、HobbyプランのStandard ProtectionはPreviewやDeployment URLを保護しますが、Productionドメイン自体は公開状態になる仕様です。ProductionドメインまでDeployment Protectionで保護するには、プランによる制約があります。

ここも、

https://xxxxx.vercel.app

だから全部同じ扱い、

というわけではありません。

Vercelには、

  • Productionドメイン
  • Production Deployment URL
  • Preview URL
  • Alias

など複数のURL・Deploymentの概念があります。

今回のトラブルも、まさにこの違いを理解していなかったことが原因でした。

今回のトラブルを解決するために試した手順

今回の経験から、同じ問題が起きた場合は以下の順番で調べるのがおすすめです。

STEP 1:Environment Variablesを確認

Vercelの、

Settings
↓
Environment Variables

を開きます。

以下を確認します。

BASIC_AUTH_USER
BASIC_AUTH_PASSWORD

そして、

Production
Preview

が必要な環境にチェックされているか確認します。

STEP 2:Environment Variables変更後に再デプロイ

npx vercel --prod

を実行します。

環境変数は次回のProduction Deploymentから適用されるため、設定変更後は新しいDeploymentを作成します。

STEP 3:Middleware自体が動くか確認

Basic認証を一旦外して、

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

export default function middleware(request: Request) {
  return new Response("Middleware is working", {
    status: 200,
  });
}

としてみます。

npx vercel --prod

を実行します。

Production URLを開いて、

Middleware is working

が表示されれば、Middlewareは動いています。

STEP 4:Deploymentの固有URLを確認

VercelのDeployments画面から、最新Deploymentを開きます。

そのDeployment固有のURLを直接開いてみます。

ここで、

Basic認証がかかる

なら、Basic認証自体は正常です。

STEP 5:Production URLとの違いを比較

次に、

Deployment固有URL

と、

Production URL

を比較します。

もし、

Deployment固有URL
→ Basic認証あり

Production URL
→ Basic認証なし

なら、コードではなくDeploymentの紐付きを疑います。

STEP 6:aliasを確認

ターミナルで、

npx vercel alias ls

を実行します。

ここで、

Production URL
↓
古いDeployment

となっていないか確認します。

今回の私のケースでは、ここでProduction URLが20日前の古いDeploymentにAliasされていることが判明しました。

STEP 7:正しいDeploymentをProductionへ昇格

正しいDeploymentが分かったら、

npx vercel promote <Deployment URL>

を実行します。

Vercel公式でも vercel promote は既存DeploymentをCurrentとしてProductionへ昇格させる用途で案内されています。

STEP 8:Production URLを再確認

最後にProduction URLを、

  • 通常ブラウザ
  • シークレットウィンドウ

などで確認します。

Basic認証のダイアログが表示されれば成功です。

Vercel Basic認証で困ったときのチェックリスト

最後に、今回の経験をチェックリストにまとめます。

  • middleware.tsがプロジェクトルートにある
  • package.jsonと同じ階層にある
  • HTMLサイトならpackage.jsonに”type”:”module”を設定している
  • Environment Variablesを設定している
  • BASIC_AUTH_USERを設定している
  • BASIC_AUTH_PASSWORDを設定している
  • Production環境にチェックが入っている
  • 環境変数変更後にProductionへ再デプロイしている
  • Middleware単体で動作確認した
  • Deployment固有URLで動作確認した
  • Production URLでも確認した
  • vercel alias lsでAliasを確認した
  • Production URLが古いDeploymentを指していないか確認した
  • 必要ならvercel promoteで正しいDeploymentをCurrentにした
  • Vercel Authenticationを安易にOFFにしていない

まとめ

今回、Vercel上のHTMLサイトにBasic認証を設定してみて、一番勉強になったのは、

「Basic認証が動かない=Basic認証のコードが間違っている」とは限らない

ということでした。

最初は、

HTMLサイトだから? 独自ドメインじゃないから? 環境変数が反映されていない?

と考えていました。

しかし、実際には、

Middleware

正常

Basic認証

正常

Production Deployment

正常

Production URL

古いDeploymentを参照

という状態でした。

最終的には、

npx vercel alias ls

でProduction URLとDeploymentの紐付きを確認し、

npx vercel promote <正しいDeployment URL>

で正しいDeploymentをProductionとして反映することで解決できました。

Vercelは非常に簡単にデプロイできる一方で、Deployment・Preview・Production・Alias・Generated URLなどの概念が少し複雑です。

特に「デプロイは成功しているのに、本番URLだけ古い」という場合は、コードを何度も書き換える前に、

npx vercel alias ls

を確認してみると、思わぬところに原因が見つかるかもしれません。

また、VercelにはVercel Authenticationという便利なDeployment保護機能がありますが、今回のように「Vercelアカウントではなく、サイト独自のユーザー名・パスワードでアクセス制限したい」というケースでは、Vercel AuthenticationをとりあえずOFFにするのではなく、Deployment Protectionの仕組みと自前のBasic認証を分けて考えることが重要だと感じました。Vercel Authenticationを無効化すると既存Deploymentの保護状態にも影響するため、設定変更は慎重に行うべきです。

今回のような「HTMLだけ」「独自ドメインなし」「Vercelの vercel.app URLを利用」という構成でも、VercelのRouting Middlewareを利用すればBasic認証を実装できます。

また、フレームワークを使っていないHTMLサイトでは tsconfig.json が存在しない場合があります。その状態で process.env を使用するとTypeScriptのエラーが出ることがあるため、@types/node のインストールに加えて tsconfig.json の types に node を指定する必要がありました。Vercelの設定だけでなく、Middlewareを動かすためのTypeScript環境も確認することが、今回のトラブル解決につながりました。

上書きしかけた話もあるのでご興味ある方はご覧ください👇

Vercelで別プロジェクトを上書きしかけた話 ―― 原因は複製した.vercelだった
はじめに個人開発でつくった静的サイト(HTML1枚のツール)に、ファビコンとOGP画像を追加してVercelにデプロイしました。ところが「画像が表示されない!」「別のアプリを上書きしちゃったかも!?」と、かなり肝を冷やす出来事があったので、…