AWS Cognitoを使ってサーバレスアプリケーションに認証をつける

AWS Logo

前回のアプリケーションに、AWS Cognitoを使って認証機能をつけた。

認証はメールアドレスとパスワードで行う。初めにサインアップを行う。メールアドレスとパスワードを入力して登録すると、アクティベーションコードが書かれたメールが届く。アクティベーションコードを入力すると登録が完了する。その後、ログインが可能となる。

また、Cognitoでログインしたユーザのみが、自分のデータにアクセスできるようにする。データアクセスはAPI Gatewayを使わずにS3のデータを直接取得している。

AWS Cognitoの設定

Cognitoの設定を行う。ユーザプールとフェデレーテッドアイデンティティの2つの設定を行う必要がある。

ユーザプールの設定

ユーザプールの設定は、画面に表示される内容を選択していくだけ。

AWS Cognito

AWS Cognito

フェデレーテッドアイデンティティの設定

ロールを作成することになるので、IAMの権限が必要となるので要注意。

AWS Cognito

AWS Cognito

AWS Cognito

AWS Cognito

AWS S3の設定

AWS S3のデータは、静的ホスティングをしていると、誰でも閲覧することができる。ユーザに自分だけのデータを見せるには権限設定を行う必要がある。

IAM ロール - Amazon Cognitoを参考にバケットポリシーの設定を行った。

認証周りを実装

aws/amazon-cognito-identity-jsを使って、認証周りを実装していく。README通りに実装して動いたので、簡単だった。

vuexを使っているので、/store/modules/auth.jsとして実装を行なった。全体のソースはeiKatou/Bango_frontendを参照してほしい。

認証を使用してS3のデータを取得

AWS.config.credentialsにJWT Tokenを設定して、S3のオブジェクトを取得する。そのため、JWT Tokenは保持しておかないといけない。

悩んだところ

S3のCORSの設定

以下のエラーとなった。

Failed to load resource: Preflight response is not successful

これは、S3のCORSの設定が出来ていないことが原因だった。

identityPoolIdの指定

以下のエラーとなった。

ValidationException: 1 validation error detected: Value ‘ap-northeast’ at ‘identityPoolId’ failed to satisfy constraint: Member must satisfy regular expression pattern: [\w-]+:[0-9a-f-]+

identityPoolIdが誤っている。ユーザプールのIDを指定するのではなく、フェデレーテッドアイデンティティのIDを指定しないといけない。「ap-northeast-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX」形式の値である。

cognito-identity.amazonaws.com:subとは?

${cognito-identity.amazonaws.com:sub}をバケットポリシーに書いているけど、これは実際に何を指定するのか?これは、アイデンティティIDである。フェデレーテッドアイデンティティ > IDブラウザから確認できる。

Vue.jsで非同期処理後のUI更新

S3上の画像を取得した後、表示を更新する必要があるが、オブジェクトを書き換えても表示できなかった。

Vue.js で表示したデータの更新とイベント処理 | Cubixを参考に、$setを利用するようにした。

参考

以下のサイトを参考にして、無事に実装することができた。感謝!