AWS+Reactアプリ作成入門(Cognito編)
AWS+Reactアプリ作成入門(S3編)
AWS+Reactアプリ作成入門(DynamoDB編)
AWS+Reactアプリ作成入門(IAM Role編)
AWS+Reactアプリ作成入門(ログイン後のAdmin編)
今回作成したアプリ ==>久喜SNS
前回はユーザ認証(Cognito)周りを中心に述べましたが、今回はS3の利用について述べたいと思います。S3は2つの目的で使います。画像の保存とReactアプリの保存です。Reactアプリの開発時は別サーバで行い、完成したらS3にdeployします。
まずAWSコンソールでS3にバケットを作成します。Reactアプリを走らせますので静的ホスティングをONにします。プログラムをdeployした時に誰でもアクセスできるように、以下のようにバケットポリシーを設定します。これで誰でもRead Onlyでプログラムにアクセスでき、ホスティングのページに示されたURLにアクセスするとプログラムが起動されます。Cognitoでプログラムの実行に権限を与えることはできますが、バケットポリシーはプログラムの実行以前の、プログラムのロードに必要となります。プログラムから画像をアップロードしたり削除したりするCognitoの権限(Role)については別の機会にしまします。
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"AddPerm",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::examplebucket/*"]
}
]
}
公式サイト:Granting Read-Only Permission to an Anonymous User
Cognitoは面倒でしたが、S3はシンプルです。信頼性が高く低価格なので、認証が不要であれば、簡単にReactアプリを作成し、以下のコマンド一発でdeployすることが可能です。react-create-appで作成したプロジェクトのディレクトリーで実行します。この辺がMeteorにない魅力ですね。
npm run build && aws s3 sync build/ s3://バケット名
このコマンドを使うためには予めaws-cliを設定しておく必要があります。ついでですのでその手順を載せておきます。
1.AWS-CLIのインストール
公式サイト「AWS CLI のインストールと設定」に従って行います。
http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html
(1)インストール
次のコマンドでインストールできます。
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
sudo pip install awscli
aws help
(2)設定
まずAWSコンソールのIAM画面のユーザで自分を検索し、アクセスキーとシークレットキーの入手します。認証情報タブでアクセスキーの作成をクリックするとポップアップにシークレッドキーが表示されますので、忘れずにコピーしておいてください。
aws configure
AWS Access Key ID [None]: AKIAXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
(3)確認
念のため確認しておきます。これでaws-cliが使えるようになりました。
$ cat ~/.aws/credentials
[default]
aws_access_key_id = AKIAXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXX
$ cat ~/.aws/config
[default]
output = json
region = ap-northeast-1
2.画像のアップロード
ReactアプリからS3にアクセスするためには権限が必要となります。権限は非ログインユーザとログインユーザにそれぞれ付与されます。そのためにはCognitoの設定が必要となりますが、これについては前回述べましたので参照してください。
まずファイル選択ですが以下のJSXで行います
<input type="file" onChange={this.handleFileChange.bind(this)}/>
this.state.fileに選択したファイルを保存します。e.target.files[0]で選択したファイルにアクセスできます。
handleFileChange(e) {
this.setState({file: e.target.files[0]});
}
送信ボタンを押された時のハンドラーの一部です。通常callbackの中で処理を行いますので、予め _self=this としていると仮定してください。s3.putObject()で画像ファイルをアップロードしています。一応 Metadata も設定していますが、今回は使っていないので不要です。
if (!_self.state.file.name.match(/^[0-9a-zA-Z\.\_\-]*$/)) {
handleErrorFunc('エラー:ファイル名は小文字の英数字と . - _ しか使えません: '+_self.state.file.name );
return;
}
filename = 'contents/images/'+identityId+'/'+_self.state.file.name;
fileType = _self.state.file.type;
var params = {
Bucket: bucketname,
Key: filename,
ContentType: _self.state.file.type,
Body: _self.state.file,
Metadata: {
data: JSON.stringify({
identityId: identityId,
uploadTime: uploadTime,
uploadDate: uploadDate
})
}
};
var s3 = new AWS.S3();
s3.putObject(params, function(err, data) {
if(err) {
console.log("Err: upload failed :" +err);
} else {
console.log("Success: upload ok");
}
});
3.画像の参照
上で作成したfilename変数を使えば、画像は以下のURLで参照できます。実際はfilenameはDynamoDBのテーブルに保存してあるので、そこから取り出してURLを作成することになります。
const imgurl = 'http://'+bucketname+'.s3-'+appConfig.region+'.amazonaws.com/'+filename;
4.画像の削除
画像の削除も簡単です
const s3 = new AWS.S3();
const params1 = {
Bucket: bucketname,
Key: item.filename,
};
s3.deleteObject(params1, function(err, data) {
if (err) console.log(err); // an error occurred
else console.log("### delete image ok"); // successful response
});
5.キャッシュファイル
DynamoDBは課金制ですし、安いスループットに設定しているので、トップページにキャッシュを設けることにしました。これは3番目のS3の使い方になります。
トップページは常に現在の投稿の一覧を取得し表示してますので、DyanmoDBにqueryを発行しています。この投稿の一覧をJSONファイルとしてS3にキャッシュします。新たな投稿や編集があった場合にキャッシュを削除します。
var params = {
Bucket: bucketname,
Key: cachepath,
ContentType: 'application/json',
Body: JSON.stringify(data.Items)
};
s3.putObject(params, function(err, data) {
if (err) console.log("### cache upload error",err, err.stack);
else console.log("### cache upload successful"+data);
});
キャッシュの削除や参照については割愛します。
今回はこれで終わりますが、DynamoDBなどは次回以降に書いていきたいと思います。