fireball

FirebaseのホスティングでBasic認証をかけた状態でAngularサイトを公開する方法

みなさんFirebase使っていますか?自分も絶賛愛用中です。

今までAngularで作ったSPAは【過去記事】S3+CloudFront+Route53+SSL+http2+AngularでSPAを配信する方法でデプロイしていたんですけど、Firebaseは便利なCLIでコマンド一発でデプロイ出来ますので、浮気性の自分はAWSからGCPにすぐに乗り換えてしまいましたw

ところで皆さんは、こういったSPAをBasic認証で公開したいと思った事はありませんか?さすがに簡易的な認証であるために、本格的なユーザー管理には使えないです。しかし、例えばstaging環境で公開したサイトを第三者には見られず、内々だけで出来栄えを確認したいという需要もあるかと思います。こういう場合はサイト全体にBasic認証をかけて公開できれば便利ですよね。

そこで今回はFirebaseでAngularをホスティングする際に、Basic認証をかけて公開する方法について考えて行きたいと思います。

AngularプロジェクトディレクトリからFirebaseの初期化

まずはご自身のAngularプロジェクトからFirebaseの設定をしていきます。FirebaseCLIを事前にインストールしておき、Angularプロジェクトディレクトリ内から以下のコマンドを実行します。

firebase init

インタラクティブに設定が進んでいきます。最初に以下のように問われます。

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press  to select)

この時にHostingとFunctionsを両方選択するようにします

次にデフォルトのプロジェクトを問われます。

? Select a default Firebase project for this directory:

ご自身がホスティングしたいプロジェクトを選択します。

次にCloud Functionsで使うデフォルトの言語が問われます。

? What language would you like to use to write Cloud Functions? (Use arrow keys)

自分はTypeScript大好きなのでそれを選択します。今回の記事ではTypeScriptを使って説明をしていきます。

また残りの設定は、デフォルトのYesを選択し続ければOKです。

終盤に以下のように問われます。

What do you want to use as your public directory?

この時、デフォルトのpublicでも問題無いんですけど、自分はあえてdummyとしています。理由は後述します。

Configure as a single-page app (rewrite all urls to /index.html)?

このように問われたらyesを選択します。

以上でCLIによる初期設定は完了です。作られたファイルとディレクトリは以下のようになるはずです。

firebase init

Firebase FunctionsからAngularを配信するようにする

通常のホスティングでしたら、publicフォルダ(今回はdummyに変更済)にビルドしたAngularファイル郡を突っ込んでCLIをつかって公開するだけなのですが、今回はBasic認証をかけたいという事で一手間加えます。

結論から言うと、publicフォルダに直接Basic認証をかけることは出来ないので、Hostingは使わずにビルドしたAngularファイルをFirebase Functionsにデプロイしていきます。

Functionsディレクトリ内から必要なモジュールをインストール

Angularプロジェクトに必要なモジュールはプロジェクトディレクトリ直下のnode_modulesディレクトリに格納されていますが、今回はFirebase Functions経由でAngularを公開します。まずはFunctionsディレクトリに入ります。

cd functions

次にBasic認証に必要なパッケージをインストールしていきます。

npm i --save basic-auth-connect express
npm i --save-dev @types/express

Basic認証に必要なコードを書く

必要なパッケージをインストールしたら、コードを書きます。コードと言っても大したこと無いのですが…

import * as functions from 'firebase-functions';
import * as express from 'express';
const basicAuth = require('basic-auth-connect');

const app = express();

app.all('/*', basicAuth(function (user: string, password: string) {
  return user === 'username' && password === 'password';
}));

export const basic = functions.https.onRequest(app.use(express.static(__dirname + '/../dist/')));

functionsディレクトリ内にdistディレクトリがあり、そこからstaticなファイルをbasic認証経由で公開するというコードです。

ちなみにこのfunctionがビルドされるのはlibディレクトリですので、そこからdistディレクトリを相対的に見る必要があります。

なおdistディレクトリはAngularのビルド時に自動的に作成できるので、意図的に作る必要はありません。

functionsディレクトリ内にAngularファイルをビルドする

次にfunctionsディレクトリ内のdistディレクトリにAngularファイルをビルドします。

いったんプロジェクトディレクトリに戻ります。

cd ../

output-pathオプションをつけてビルドします。

npx ng build --output-path=./functions/dist

firebase.jsonファイルの変更

firebase.jsonファイルを変更し、Hostingするディレクトリ(今回はdummyディレクトリ)にアクセスがあった場合、Functionが起動されるように設定します。

"hosting": {
    "public": "dummy",
      "ignore": [
        "firebase.json",
        "**/.*",
        "**/node_modules/**"
      ],
      "rewrites": [
        {
          "source": "**",
          "function": "userStg"
        }
      ]
  }

またdummyディレクトリは何も意味をなさない文字通りdummyなディレクトリなのですが、ディレクトリ自体は必要なので中に.gitkeepファイルを配置しておきます。

デプロイする

ここまで来たらいよいよデプロイです。以下のコマンドを実行します。

firebase deploy

以上でおしまいです。