Cognito IDプールを使用したお問い合わせフォームの作成(認証されないアクセス)
はじめに
おはようございます、加藤です。気づけば入社して8ヶ月目でした、最近時間の流れが早いです。
今回は、CognitoのIDプールを使用した一時的な認証情報の取得とサンプルコードを紹介します。
パブリックログインプロバイダー(Facebook、Google+、Login with Amazon など)は使用しません、認証されていないアクセスが対象です。
それと今回はCognito IDプールのみの内容ですユーザープールは一切使用しません(自分は勉強する時にかなり混乱しました...)。
認証されていないアクセスのフロー
最初にCognitoで認証されていないアクセスのフローを説明します。
Deviceが最終的に欲しいものはSTSによって発行される一時的な認証情報です。
STSへのアクセスはCognitoが行うので、DeviceはCognitoにのみアクセスします。
Cognitoは認証される/されないによって、取得する認証情報(IAMロール)を分けることができます。
今回作るもの
作成するものはお問い合わせフォームです。
Webサイトにアクセスし、タイトルと内容を記載して送信ボタンを押すと、記載内容がデータ保存用バケットにJSONで保存されるという仕組みを作ってみます。
やってみた
S3バケットの作成
Webサイト用とデータ保存用のS3バケットを作成します。
Webサイト用
バケットポリシー
パブリックアクセスを許可するためにアクセス権限の項目でバケットポリシーを設定します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AddPerm", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<<YOUR_WEBSITE_BUCKET_NAME>>/*" } ] }
Static website hosting
Webサイトとして使用するために、プロパティの項目でStatic website hostingを有効にします。インデックスドキュメントはindex.htmlに設定します。
後で使用するので、エンドポイントをメモしておいてください。
データ保存用
CORSの設定
Webサイト用とデータ保存用のバケットを分けている為、クロスドメイン通信が必要です。
バケットへのPUTを許可するCORS(CrossDomainResourceSharing)を設定します。
ここで先程メモしたWebサイト用バケットのエンドポイントを使用します。
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin><<YOUR_WEBSITE_BUCKET_ENDPOINT>></AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
Cognito IDプールの作成
ID プールを作成します。プール名は任意の名前でOKです。
認証されていないIDに対してアクセスを有効にするにチェックを入れて作成します。
作成すると、Auth/Unauthに割り当てるIAMロールの設定を求められます。
デフォルトの新規作成のまま進めます。Unauthのロール名は後でポリシーを割り当てるのに使用するのでメモしておきます。
作成が完了すると認証情報取得の為のサンプルコードが表示されます。
IDプールのIDをメモしておきましょう。
UnauthのIAMロールへポリシーの割り当て
UnauthのIAMロール(IDプール名がsampleならCognito_sampleUnauth_Role)にデータ保存用バケットへのアクセス権限を与えます。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::<<YOUR_DATA_BUCKET_NAME>>/*" } ] }
Webサイトの作成
Webサイトを作成します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.311.0.min.js"></script> <title>Sample</title> <script> var $id = function (id) { return document.getElementById(id);}; AWS.config.region = "ap-northeast-1" AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: '<<YOUR_IDENTITY_POOL_ID>>', }); function uploadFile() { var s3BucketName = "<<YOUR_DATA_BUCKET_NAME>>" var now = new Date(); var obj = {"title":$id("title").value, "contents":$id("contents").value, "date": now.toLocaleString()}; var s3 = new AWS.S3({params: {Bucket: s3BucketName}}); var blob = new Blob([JSON.stringify(obj, null, 2)], {type:'text/plain'}); s3.putObject({Key: "uploads/"+now.getTime()+".txt", ContentType: "text/plain", Body: blob, ACL: "public-read"}, function(err, data) { if (data !== null) { alert("アップロード成功"); } else { alert("アップロード失敗:" + err.message); } }); } </script> </head> <body> <div> <div> <form> <table> <tr> <th>タイトル</th> <td> <input id ="title" type="text" name="title" class="titletext fontchange" maxlength="40" value="" /> </td> </tr> <tr> <th>内容</th> <td> <TEXTAREA id="contents" cols="40" rows="6" name="contents" class="fontchange"></TEXTAREA> </td> </tr> </table> <div id="button_area" class="clearfix"> <input onclick="uploadFile();" type="button" value="送信" id="css_button" class="button_right" /> </div> </form> </div> </div> </body> </html> <!---参考元: https://www.i-enter.co.jp/blog/blog/2015/02/03/s3/--->
作成したindex.htmlをWebサイト用のバケットのルートにアップロードします。
動作テスト
メモしておいたWebサイト用バケットのエンドポイントにブラウザでアクセスします。
タイトルと内容を適当に入力して送信ボタンを押します、アップロード成功と表示されればOKです。
データ保存用バケットを確認してみましょう。
uploadsフォルダの中にテキストファイルが作成されており、下記の様になっていれば最終確認OKです。
{ "title": "aaa", "contents": "bbbbb", "date": "2018/9/9 10:19:27" }
参考
- (MBL402) Mobile Identity Management & Data Sync Using Amazon Cognito
- 【 AWS 】Amazon Cognitoで認証を行って、S3にファイルをアップロードする仕組みを実装してみた(1) - Qiita
- Amazon CognitoとS3で問い合わせフォームを作る – 陽気なシステム屋が世界を変える
- パブリックログインプロバイダー(Facebook、Google+、Login with Amazon など)
あとがき
Cognito IDプールについて認証される場合のフローは情報が沢山あったのですが、認証されない場合のフロー情報がすぐに見つからず苦労しました。
最初の載せたアクセスのフローは自分で作ったものなので間違いや追加した方が良いものがあればコメントお願いします。