CloudFront + S3 + Cognito + AWS Amplify + Vue.js で会員制サイトをサーバーレスで構築

概要

下記のようなものをサーバーレスで構築してみた。

ユーザー登録ページ: /public/pages/signup.html

尋常にメールアドレスとパスワードで登録。
登録するとログインページにリダイレクトするが、 ログインする前に Cognito から届くメールアドレス確認メール中の URL をクリックして登録完了する必要がある。

ログインページ: /public/pages/signin.html

何の変哲もない。

ちなみに、 URLパスの pages という部分は、 CloudFront 周りでいろいろ試行錯誤した際の痕跡なので、特に意味はない。

ユーザー限定公開ページ: /private/index.html

ログイン後にしれっとリダイレクトする限定公開ページ。
CATAAS (Cat as a service) という API を使ってランダムに猫画像を表示するだけ。

ログアウトページ: /public/pages/signout.html

これまたしれっとログアウト処理後にログインページへリダイレクトするだけ。

イカれたメンバーを紹介するぜ

公開領域

  • CloudFront
  • S3
  • Cognito
  • Vue.js
  • AWS Amplify

AWS におけるサーバーレスで会員制サイトを実装する際に、健康で文化的な最低限度の生活を送るための技術スタック[要出典]。 ユーザー登録ページとログインページ、ログアウトページを構築するための認証基盤と、そのフロントエンドを構成するために使用。

Vue.js というと SPA (single-page application) のニオイがプンプンするが、.htaccess 的な魔術が難しい CloudFront + S3 で SPA を配信しようとすると、かなり力技が必要になる ので、素直に MPA (multi-page application) として出力したほうが良さそう。

非公開領域 (会員限定)

  • CloudFront
  • Lambda@Edge
  • S3
  • API Gateway
  • Lambda
  • Serverless Framework

会員限定コンテンツの配信部分と、そこへアクセスするための CloudFront 用署名付き Cookie (認証情報) 発行処理部分を構成するために使用。

当初、 API Gateway から署名付き Cookie をブラウザに食わせようとしたところ、 API Gateway から複数の set-cookie ヘッダーをまともに発行できないという想定外の地雷が埋め込まれていたので要注意。今回はクライアント側 JS で Cookie を設定するようにした。

また、署名付き URL / Cookie 有効時に Apache httpd で言うところの DirectoryIndex ( /dir/ アクセス時に /dir/index.html の内容を表示する機能) が効かないので Lambda@Edge で対策した。

同じく DirectorySlash ( /dir のようなパスで実在するディレクトリへアクセスした際に、ケツスラッシュを補完して /dir/ にリダイレクトする機能) も効かないので、実運用時はもっと頑張る必要があるかと。

おわりに

「サーバーレスで真面目にサービスとして Botサイトを作りたいけど、認証基盤どうしよう……」
って言う場合も大丈夫。
そう、 Firebase Cognito ならね。

コード

hiraro/cloudfront_s3_with_cognito_auth_sample