spaで作った管理画面を安全に公開してみた。


概要

spa で管理画面を作ると問題があって
javascript のコードを解析すれば誰でも画面内容が覗けるようになってしまいます。
未ログインの状態でも管理画面の内容が覗きてしまうのは流石にまずい。
対処したときのメモを残しておきます。

結論

s3 に入っているビルド済の bundle ファイルを読み込む直前にベーシック認証を挟む。
その場合、lambda を使いたいので s3 の前に cloudfront を挟む必要あり。
これで誰でも管理画面の内容が見れる状態は回避できるはず。

前提条件

vue cli 3.X

アーキテクチャ

設定手順

s3

デフォルト設定でバケット作成 ※手順は省略します。

cloud front

ディストリビューション作成

  • サイドメニュー → ディストリビューションを作成

    • オリジンドメイン:s3 バケットを指定
      • S3 バケットアクセス:はい、OAI を使用します
      • オリジンアクセスアイデンティティ:新しい OAI を作成
      • バケットポリシー:はい、バケットポリシーを自動で更新します。
    • キャッシュキーとオリジンリクエスト
      • Legacy cache settings
        • ヘッダー:次のキャッシュを含める
        • ヘッダーを追加:Authorization
        • オブジェクトキャッシュ:customize
          • 最小 TTL:0
          • 最大 TTL:0
          • デフォルト TTL:0
    • デフォルトルートオブジェクト-オプション:index.html
lamda 関数作成
  • サイドメニュー → 関数 → 関数を作成

    • 関数コード:

      function handler(event) {
        var request = event.request
        var headers = request.headers
      
        // ユーザー名:root, パスワード:P@ssw0rd
        // echo -n root:P@ssw0rd | base64
        var authString = "Basic cm9vdDpQQHNzdzByZA=="
      
        if (
          typeof headers.authorization === "undefined" ||
          headers.authorization.value !== authString
        ) {
          return {
            statusCode: 401,
            statusDescription: "Unauthorized",
            headers: { "www-authenticate": { value: "Basic" } },
          }
        }
      
        return request
      }
      
    • 関数を発行

      • ディストリビューション:作成した cloudfront ディストリビューションを指定
      • イベントタイプ:Viewr Request

これで cloudfront のドメインにアクセスするとベーシック認証のダイアログが表示されるはずです。

所感

cloudfront の使い方間違ってる気がするけど本当にこのやり方でいいんだろうか・・・・
もっといいやり方ないのかな。