Vercel で Basic 認証付きのプレビュー環境を作る

Vercel は Serverless functions が使えるので、サーバーを立てて、そこから静的コンテンツを配信することができます。

Vercel のコンテンツにパスワード付ける機能はオプション機能なので有料ですが、Serverless functions を利用すれば無料プランの範囲内で Basic 認証付きの環境を作ることができたので、その方法をメモ。

今回は Node.js を使いました。

事前にやっておくこと

  • vercel コマンドのインストール (リポジトリの連携を行っている人は必須ではない)
  • プロジェクトの public に静的コンテンツを作成しておくか npm run build のように静的コンテンツをビルドするためのコマンドを用意しておく

やること

  • プロジェクト内にエントリーポイントとなるファイルを用意する
  • vercel.json に builds, routes を記述する

プロジェクト内にエントリーポイントとなるファイルを用意する

  • 下のコードをプロジェクト配下に置く
  • Basic 認証を追加する処理、静的コンテンツの配信は static-auth を利用して簡略化しています

app.js

const protect = require('static-auth');
const safeCompare = require('safe-compare');

const USER_NAME = process.env.USER_NAME || 'admin'; // プロジェクトの環境変数を設定していた場合はそちらを適用させる
const PASSWORD = process.env.PASSWORD || 'admin';

const app = protect(
  '/',
  (username, password) => safeCompare(username, USER_NAME) && safeCompare(password, PASSWORD), // timing attack 対策
  {
    directory: `${__dirname}/public`, // public 配下のファイルを静的コンテンツとして配信する
    onAuthFailed: (res) => {
      res.end('Authentication failed')
    },
  }
)

module.exports = app

directory で指定する値も process.env で設定できたら良さそうと思って色々試してみましたが、変数展開させようとするとプレビュー環境でうまくいきませんでした。 (ローカルではうまくいったので謎....)

vercel.json に builds, routes を記述する

Vercel はデフォルトで publicフォルダをドキュメントルートとしてコンテンツを公開します。 public フォルダが存在しない場合はプロジェクトのルート直下がドキュメントルートとなります。

先程作成した app.js もそのままでは実行されません。 これを変更するために vercel.json をプロジェクトルートに作成し、以下の内容を記述します。

{
  "builds": [
    {
      "src": "app.js",
      "use": "@vercel/node" // app.js を node で実行する
    }
  ],
  "routes": [
    { "src": "/.*", "dest": "main.js" } // リソースへのアクセスを main.js を通す形に変更
  ]
}

ローカルで動作テスト、プレビュー環境への反映

プレビュー環境にあげる前にローカルで app.js が動作するかをテストします

vercel dev

ローカルで app.js が動作し、Basic 認証がかかって認証語に public 配下のコンテンツを表示することを確認できたらプレビュー環境へデプロイします。

vercel