【 AWS 】Amazon Cognitoで認証を行って、S3にファイルをアップロードする仕組みを実装してみた(1)

#  __<font color="black">はじめに</font>__ :spy:
「 __<font color="black">Amazon Cognito</font>__ 」を使って、__サーバーレスなユーザー認証を実現__してみた！
記事内容自体は、目新しいことではないかもしれませんが、自分の __<font color="black">＃備忘録</font>__ として書き残していきます。
_※ Amazon Cognitoを触ったことがない方でも読めば役に立つんじゃないかなと思います。_

# :point_right_tone2:  __<font color="black">目次</font>__

- __やりたいこと__  ( システム構成図 )
- __(1) S3で静的Webサイトをホスティングする。__
- __(2) What's Amazon Cognito !?__
- __(3) Amazon Congnitoを使って、User Poolを作成する。__
- __(4) AWS SDK(JS)を使って、ログイン基盤を作成する。__
- __(5) S3署名付きURLを生成する。__
- __参考文献__

# __<font color="black">やりたいこと</font> (システム構成図)__ :japanese_goblin:
「 __<font color="black">Amazon Cognito</font>__ 」を使って、ユーザー認証を行い、認証済みのユーザーに対して、
一時的に、「 __<font color="red">IAM</font>__ _( AWS Identity and Access Management )_ __<font color="red">Role</font>__ 」を付与すること。
署名付きURL生成？してS3へアップロード？

__・全体のシステム構成イメージ図__

|![AmazonCognito.png](https://qiita-image-store.s3.amazonaws.com/0/180432/02384776-1db0-ed86-2814-c776804a65b5.png)|
|:-:|

# __<font color="black">(1) S3で静的Webサイトをホスティングする。</font>__

<font color="black">__ユーザー認証ページを「 <font color="red">サーバーレス</font> 」で実現__</font>するために、
今回は、S3を用いた静的Webサイトのホスティングを行います。

_※S3の「Static website hosting」を有効にすると、バケットに対してHttpsアクセスが無効になります。
HTTPSアクセスをしたい場合は、CloudFront(CDN)を間に挟む必要があります。_

_手順は、下記公式サイトに記載がありますが、本記事でも少しだけ触れたいと思います。_

- [Amazon S3 での静的ウェブサイトのホスティング (公式サイト)](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WebsiteHosting.html)
- [例 : 静的ウェブサイトをセットアップする](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/HostingWebsiteOnS3Setup.html)
- [Amazon S3による静的Webサイトホスティング](https://www.slideshare.net/horiyasu/amazon-s3web-27138902)

## __01. S3バケットを新規作成__
新しいバケットを作成します。
デフォルトのエンドポイントは、下記になります。

[http://<-your_bucket_name->.s3-website-<-your_region_name->.amazonaws.com]()

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/f8bca121-2ba9-0430-a558-cec39db9f56e.png)|
|:-:|



## __02. Webサイトホスティングの設定を追加__
新しく作成したS3のプロパティ__「Static website hosting」__を編集します。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/eb7cdc09-b2d7-b24f-f763-bc8dd802abd0.png)|
|:-:|

ラジオボックスが表示されるので、
__「このバケットを使用してウェブサイトをホストする」__
を選択します。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/5a92bdc4-4bbf-e187-4432-bf56411a424f.png)|
|:-:|

インデックスドキュメントの欄が空欄なので、
__「index.html」__と入力し、保存ボタンを押下します。

## __03. バケットポリシーの追加__
バケットを作成した状態だと外部からは非公開なので、
バケットポリシーを追加し、パブリックからのアクセスを許可します。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/3b0817e5-5288-0277-9c99-71b29fd8b488.png)|
|:-:|

バケットポリシーエディターに下記コードを追加。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<アクセスを許可したバケット名>/*"
        }
    ]
}
```

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/c0e7cebb-337b-4987-007a-2c0d861bc0e3.png)|
|:-:|

## __04. 対象バケットに ```index.html``` をアップロード__
実際に、アクセスのあった際に表示される```index.html```ファイルをアップロードします。

```index.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8" />
  <title>qiita</title>
  <!--[if IE]>
   <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
  <style>
   article, aside, dialog, figure, footer, header,
   hgroup, menu, nav, section { display: block; }
  </style>
 </head>
 <body>
  <p> Hello [Bucket名]! </p>
 </body>
</html>
```


## __05. 検証__
実際にアクセスしてみる。

[http://<-your_bucket_name->.s3-website-<-your_region_name->.amazonaws.com]()

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/9b397431-508b-6100-1040-a54688140f34.png)|
|:-:|

上記```index.html```ファイルの```<p>```タグで囲ったテキストが表示されていれば成功です。
続いて、__ユーザー認証に必要な__「 __<font color="black">Amazon Cognito User Pools</font>__ 」を作成したいと思います。


# <font color="black">__(2) What's Amazon Cognito !?__</font>

__Amazon Cognito__ には、__大きく3つの機能__があります。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/f8f9b703-3c10-fb00-ae39-65aad5417276.png)|
|:-:|

- __Amazon Cognito User Pools__
- __Amazon Cognito Federated Identities__
- __Amazon Cognito Sync__

# <font color="black">__(3) Amazon Congnitoを使ってUser Poolsを作成する。__</font>

## __Amazon Cognito User Pools__ とは？
> User Poolsを使うと、誰でも手軽にユーザーディレクトリの作成、管理を行うことができ、
モバイルアプリやウェブアプリケーションにサインアップやサインインを簡単に追加することができます。
[Amazon Cognito とは ( 公式サイト )](http://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/what-is-amazon-cognito.html)

CognitoのUserPoolを作成していきます。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/e904353e-8c0e-13e9-3684-6fff257608ca.png)|
|:-:|

サインインする際の認証方法と、ユーザー情報の標準属性について設定することができます。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/dd7fc1aa-805d-2d35-351e-7e48eccf9151.png)|
|:-:|

「ユーザーパスワードの強度」と「サインアップ権限の付与有無」、「ユーザーアカウントの有効期限」等を設定することができます。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/1cd7de35-a47f-2df9-61da-e08203d9d571.png)|
|:-:|

__多要素認証( MFA:Multi-Factor Authentication )__の設定や、SMSメッセージ送信用のRole作成、指定等の設定ができます。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/62027da1-0686-67d2-cbf9-20d675bbe2cf.png)|
|:-:|

メールアドレス検証時のメッセージを設定することができます。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/cab9852f-6fdd-1a48-4753-226f6cd2b08d.png)|
|:-:|

最終確認を終え、「__プールの作成__」ボタンを押下すると、新しいプールが作成されます。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/638c4b62-4693-3178-1013-b393b261c390.png)|
|:-:|

今回は、ここまで。次の記事でこの実装の続きについて、記載したいと思います。

# __<font color="black">・トラブルシューティング</font>__

#### __1. S3でホスティングしたWebサイトはHTTPSアクセスすることができない!?__
> <font color="red">A. とりあえず、下記方法でHTTPS対応することができるみたい。</font>
[AWS S3でのhttps対応含む静的ウェブサイト公開](https://qiita.com/THHacker/items/11eadffe6b3ce3491e3b)

# __<font color="black">・重要なキーワード</font>__

#### __<font color="red">フェデレーション</font> ( Federation ) とは？__

> 一度認証を通れば、その認証情報を使って、許可されている全てのサービスを使えるようにする仕組み。
・ [IT用語辞典 - Federation](http://wa3.i-3-i.info/word12731.html)

#### __SAML__ ( Security Assertion Markup Language ) とは？
> SAMLとは、Security Assertion Markup Language の略称で、OASISによって策定された
異なるインターネットドメイン間でユーザー認証を行うためにXMLベースにした標準規格です。
2002年に策定され、2005年にはバージョン2.0となっています。
[SAMLとは (onelogin)](http://www.cybernet.co.jp/onelogin/function/saml.html)


# __<font color="black">※ 執筆途中に大変参考にさせていただいたサイト</font>__

執筆者のみなさん、情報を公開してくださってありがとうございます。

- [AWS Black Belt Online Seminar 2017 AWS Cognito]()
- [AWS SDK for JavaScriptでCognito User Poolsを使ったログイン画面を作ってみた](https://dev.classmethod.jp/cloud/aws/login-form-by-using-aws-sdk-for-javascript/)
- [[ Serverless ] Cognito、S3、Lambdaで認証機能付きのWebサイトを作ってみました](https://qiita.com/jobbin/items/d2fc0f714eb1f1cfc965)
- [AWS Cognito UserPools を Cordova (Javascript) で使う最初の一歩](https://qiita.com/exabugs/items/c17b403c82c56acb4453)

上記サイトを読んでからやると、実装完了までのスピードが格段と上がること間違いなし！

# __<font color="black">さいごに</font>__ :man_tone4:
最後までお読みいただき、ありがとうございました。
引き続き、詳細のアップデートがあれば記事も更新していく予定です。