サーバーレスで画像をトリミング→S3にアップロード(1)

#概要
クライアントサイドのJavascriptのみで画像のトリミング・S3へのアップロードを行います。
![スクリーンショット 2018-12-19 17.37.37.png](https://qiita-image-store.s3.amazonaws.com/0/204464/7413b80e-11fd-a40a-f128-4aec6e3315cf.png)

今回はAWSの設定が中心で、jsのコードは次回にします。

#動機
SNSのプロフィール画像設定時など、画像をユーザーにトリミングさせてサーバーへアップロードするという機能はしばしば必要になることと思います。

その際、通常でしたらクライアントサイド・サーバーサイド両方でプログラムを書き、クライアントサイドからは画像とトリミング情報(座標・サイズなど)をサーバーサイドに送信し、実際の画像の切り抜き・ストレージへの格納はサーバーサイドで行うといったことがされるようです。
(参考：[JavaScriptで画像をトリミングしてアバター画像を作ってみる](https://qiita.com/papillon/items/8d1206a4cb9a589acd16))

ですが、ただ画像のトリミングとストレージへのアップロードだけをしたい場合にサーバーサイドのプログラムまでかくのは少々オーバーのように感じます。そこで、今回は画像のトリミング・Amazon S3へのアップロードを全てクライアントサイドのJavascriptで行ってみました。

#前提
AWSアカウントは取得している前提で話を進めます。

#方法
##AWS
###Amazon Cognito
Amazon Congnitoは、アプリケーションからAWSのリソースにアクセスするときの認証周りで使用します。「このアプリからはここまでのリソースにアクセスできる」といったように、アクセスのスコープを詳細に設定することが可能です。

Cognitoの理解には以下のページが参考になると思います。
[一般的な Amazon Cognito シナリオ](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-scenarios.html)

まずはAmazon CognitoでIDプールを作成します。以下の画像のように設定してください。(IDプール名は適当に決めてください)

![ID pool.png](https://qiita-image-store.s3.amazonaws.com/0/204464/116a4bc4-7a53-7fb4-df4e-28773690c0f2.png)

「プールの作成」をクリックすると続いてIAMロールの作成に入りますが、これはデフォルトのまま許可ボタンを押していただければ結構です。

以上でIDプールの作成は完了し、プラットフォームでJavaScriptを選択すると以下のようなサンプルコードが出力されると思います。
![Sample Code.png](https://qiita-image-store.s3.amazonaws.com/0/204464/3847f19b-6e54-2a9e-3ace-b3c6ec1c39b6.png)
これは後々使うことになるのでどこかにコピーしておいてください。

###Amazon S3
続いてはAmazon S3の設定です。Amazon S3はストレージサービスで、トリミングした画像はこちらにアップロードされることになります。
EC2ではインスタンスという単位でサーバーが管理されるように、S3ではバケットという単位でストレージが管理されます。そこで、まずはバケットを作成しましょう。

「バケットを作成する」をクリックして、バケットを作成してください。バケット名のみ自由に指定して、ほかはデフォルトのまま進めてください。ただし、リージョンはCognitoIDプールを作成したときのと同じものを使用してください。

バケットを作成したら、このバケットにユーザーが画像をアップロードできるように、バケットのアクセス権限を設定してあげる必要があります。上部にある「アクセス権限」→「CORSの設定」と進んで、以下を入力し、保存を押してください。

```:CORS
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
```

以下の画像のようになるはずです。
![スクリーンショット 2018-12-19 16.04.28.png](https://qiita-image-store.s3.amazonaws.com/0/204464/8ba9fb2b-6e77-4967-9273-877d8b529759.png)


###IAM
先程作成したIDプールのユーザーがS3のバケットに画像をアップロードできるように、バケット側の設定だけではなくIDプールにアタッチされているロールも設定する必要があります。
IAMのコンソールに入り、サイドバーの「ロール」をクリックするとロールの一覧が表示されます。この中の、「Cognito_\<IDプール名>Unauth_Role」を選択してください。
以下のような画面になると思います。
![スクリーンショット 2018-12-19 16.41.40.png](https://qiita-image-store.s3.amazonaws.com/0/204464/4e9275e3-c467-16cf-c0f9-c160963201e7.png)

ここの「ポリシーをアタッチします」→「ポリシーの作成」と進み、ポリシーを作成します。以下のように入力してください。
![スクリーンショット 2018-12-19 16.52.10.png](https://qiita-image-store.s3.amazonaws.com/0/204464/7112b3fb-905c-ec7d-c53b-f5cbbdfe0e79.png)
\<バケット名\>のところにはS3で作成したバケットの名前を入力してください。

入力したら「ポリシーの確認」→ポリシー名を入力 と進め、ポリシーを作成します。
その後、作成したポリシーをロールにアタッチしてください。
以上でAWS側での設定は終わりになります。

#参考サイト
- [JavaScriptで画像をトリミングしてアバター画像を作ってみる](https://www.selfree.co.jp/2015/06/18/%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%83%AC%E3%82%B9%E3%81%A7javascript-%E3%81%A0%E3%81%91%E3%81%A7%E7%94%BB%E5%83%8F%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)