普段は静的サイトのホスティングに GitHub Pages か Netlify をつかうことが多いのですが、Basic認証をかけたい場合、GitHub Pagesでは実現できないですし、Netlifyでは有料の機能なので、どうしようかなと思っていました。
一旦は、 Heroku を使おうかなとも思ったのですが、今回は Firebase を使ってみます。
ざっと調べてみたところ、Firebase Hosting 単体では、Basic認証をかけることができないのですが、Cloud Functions と組み合わせることで実現するのがセオリーっぽいです。
Cloud Functionsは無料のSparkプランでは使用できないので、従量課金のBlazeプランでプロジェクトをつくる必要があります。
それなりに無料枠があるので、簡単なテストサイトレベルであれば無料で運用できますが、プランの切り替えが必要となるとちょっぴり緊張します。
実現方法
firebase.json
{ "hosting": { "public": "public", "rewrites": [ { "source": "**", "function": "app" } ], "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ] } }
functions/index.js
const functions = require('firebase-functions'); const express = require('express'); const basicAuth = require('basic-auth-connect'); const app = express(); app.all('/*', basicAuth((user, password) => { return user === 'user' && password === 'password'; })); app.use(express.static(__dirname + '/public/')); exports.app = functions.region('asia-northeast1').https.onRequest(app);
認証のユーザー名がuser、パスワードがpasswordに設定し、東京リージョンにデプロイする場合はこんな感じのコードを書き、publcディレクトリを空に、functioins/publicディレクトリにホスティングしたいファイルを置けばOKです。
なにが書いてあるかをざっくり読み解くと、firebase.jsonには全てのリクエスト(**)を、CloudFuncsions(app)で処理するという記述がしてあり、CloudFuncsionsではExpressで静的なホスティグをしつつ、Basic認証をかける処理が書いてあります。
Firebaseの挙動としては、リクエストがくると、まずはpublicディレクトリを探し、なければCloudFuncsions(app)を実行するようです。
なので、もしも一部認証を掛けたくないファイルがあるのであれば、functioins/publicディレクトリではなく、publcディレクトリにいれておけばOKです。