[AWS] ReactアプリでCognitoユーザープール認証を行ってみる

# Cognitoの基本

「[[AWS] Cognitoの基本まとめ](https://qiita.com/herohit-tool/items/98bdf8bf073259ba208a)」をご覧ください。

# 前提
今回はReactを使用するので、事前に

- Node.js
- npm

をインストールしておいてください。
あと、AWSアカウントの用意もお忘れなく。

# 準備
## ユーザープールの作成
まず、マネジメントコンソールにログインして、サービス「Cognito」の画面を表示します。
まだユーザープール、IDプールともに未作成のはずなので、下記のような画面になると思います。

<img width="1306" alt="cognito1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/f2e18743-430f-5512-5f0e-af2b94e7bc55.png">

ここで「ユーザープールの管理」ボタンを押します。

<img width="1121" alt="cognito2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/fa75ae1c-af85-662c-9ec0-bb4be94404be.png">

そして「ユーザープールを作成する」ボタンを押します。
すると、プール名の入力を促されるので、適当なプール名を入力してください。

<img width="1122" alt="cognito3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/7bad335b-ba5f-4c2a-31c8-43fbc9097524.png">

今回は、ここで「デフォルトを確認する」ボタンを押します。

![cognito4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/3f1bd6d4-ce5a-8807-3491-7fc813874308.png)

一応内容を確認して、一番下にある「プールの作成」ボタンを押します。
すぐに作成完了の画面が出るので、プールIDを控えておきましょう（控え忘れてもあとで確認はできます）。

<img width="852" alt="cognito5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/2dd04a97-eb45-7b10-5774-c1346cf37507.png">

## アプリクライアントの作成
今回は、外部プロバイダではなくユーザープールで認証を行うので、作成したユーザープールにアプリクライアントを作成します。
画面右側にある「アプリクライアント」を選択してください。

<img width="1149" alt="cognito6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/a94a83aa-63db-26b5-b788-7c21d780c5f0.png">

ここで「アプリクライアントの追加」リンクをクリックします。
アプリクライアント名に適当な名称を入力します。
あと、今回は簡単なサンプルにしたいので「クライアントシークレットを生成」のチェックだけ外してください。
それ以外はデフォルトのままとしておきます。

<img width="1283" alt="cognito7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/9c044373-c65a-abf6-e7c2-f09a6aa587b4.png">

「アプリクライアントの作成」ボタンを押します。
すると、画面が切り替わるので「アプリクライアントID」を控えておきましょう（これも後で確認することはできます）。

<img width="1170" alt="cognito8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/0ee5132b-256d-d034-ef42-1579ed3fad4d.png">

## IDプールの作成
ユーザープールが作成できたので、今度は、アカウントを管理するIDプールを作成します。
画面上部にある「フェデレーテッドアイデンティティ」のリンクをクリックします。

<img width="505" alt="cognito9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/3674aabb-3e8f-e617-40f1-722a9f549bf0.png">

まずはIDプール名に適当な名称を指定しましょう。

<img width="1169" alt="cognito10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/81c3677a-47d1-4d9b-c832-9053278a50ec.png">

そして、画面の下の方に移動すると「認証プロバイダー」というリンクをがあるので、これをクリックして入力領域を展開します。
ここで、ここまでに控えておいた、ユーザープールID、アプリクライアントIDを入力します。

<img width="919" alt="cognito11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/8664b71a-985b-2d0b-4fbc-b20ff49d6edd.png">

そして「プールの作成」ボタンを押します。
しばらくすると、IAMロールを作成する画面が出てきます。

<img width="1169" alt="cognito12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/d6652cde-92d8-f2a1-c72e-29a22c13cc72.png">

特に何も変更せず、そのまま「許可」ボタンを押してください。

# クライアントアプリの作成
## Reactアプリの作成
まず最初に、`create-react-app`をインストールします。

```bash
$ npm install -g create-react-app
```

続いて、下記コマンドでアプリケーションのプロジェクトを作成します。

```bash
$ create-react-app cognito-test
```

完了したら、一応正しくセットアップできているか確認してみます。

```bash
$ cd cognito-test
$ npm start
```

`http://localhost:3000/`にアクセスして、下記のような画面が表示されればOKです。
「Ctrl+C」で一度終了させてください。

<img width="781" alt="react1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/bddc9040-97e2-5d26-8d91-3c0833e6b76e.png">

## Apmplifyのインストール
今回はクライアントにJavaScriptを使うため、Amplifyを使用したいと思います。
プロジェクトのディレクトリ配下で、以下のコマンドを実行してください。

```bash
$ npm install aws-amplify aws-amplify-react @aws-amplify/ui-react
```

## Cognitoのコードを書く
### package.json
まず、上でインストールしたライブラリが追加されているか確認しましょう。
`dependencies`に、以下の2行を追記してください。

```json
    "aws-amplify": "^3.0.22",
    "aws-amplify-react": "^4.1.21",
    "@aws-amplify/ui-react": "^0.2.13"
```

### src/index.js
続いて、index.jsを以下のように修正します。

```javascript:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import Amplify from 'aws-amplify';

Amplify.configure({
  Auth: {
      identityPoolId: 'IDプールのID',
      region: 'ap-northeast-1',
      userPoolId: 'ユーザープールID',
      userPoolWebClientId: 'アプリクライアントID'
  }
});

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
```

とします。
IDプールのIDは、IDプールの画面で「IDプールの編集」から確認できます。

<img width="1272" alt="cognito13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/771073b7-aafa-2358-cb07-731d68c5eabf.png">

### src/App.js
続いて、App.jsも、下記のように書き換えてしまってください。

```javascript
import React from 'react';
import { withAuthenticator } from '@aws-amplify/ui-react';

function App() {
  return (
    <div className="App">
    </div>
  );
}

export default withAuthenticator(App);
```

以上。
これだけです、たったこれだけ。

# 動作確認
## いざ起動
まずはアプリケーションを起動します。

```bash
$ npm start
```

そして`http://localhost:3000/`にアクセスすると、画面が先ほどとは違い、以下のような画面が出てきます。
Cognitoのデフォルトの認証画面です。

<img width="649" alt="React_App.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/27682cee-fb3d-ef30-a6e2-3e75a552e401.png">

## ユーザ作成
この時点では、まだユーザを1つも登録していないので「Create account」のリンクから、ユーザを登録してみましょう。
この時、標準の設定で、メールアドレス認証を有効にしているので、メールアドレスはメールを受信できる有効なものを指定してください。

<img width="593" alt="userreg.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/d8755a7e-2924-f1f1-76ae-bf3e311e9c2f.png">

「CREATE ACCOUNT」ボタンを押すと、確認画面が表示されます。

なお、この時点でマネジメントコンソール画面でユーザープールの状態をみてみると、

<img width="1125" alt="cognito16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/913f6c56-025a-4c3b-637d-0705fad87b5e.png">

と、ユーザが作成され、Eメール確認済みが「false」になっていることが確認できます。

<img width="512" alt="cognito17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/ea709973-7706-b2f2-cdf9-159064d9ccf6.png">

では、話を戻して、Confirmation Codeに、受信したメールに記載されているコードを入力して「CONFIRM」を押してみましょう。
すると、画面が真っ白くなりますが（認証後に表示するページを指定していないため）、マネジメントコンソールの画面で確認してみると、

<img width="1109" alt="cognito19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/74aea514-032e-bd92-0a84-ce2e4e511126.png">

Eメール確認済みが「true」にかわっているかと思います。

# まとめ
認証・認可の機能を追加する、ってなかなか敷居が高いイメージでしたが、さくっとできてしまいました。
次は、FacebookなどからSSOする方法について解説したいと思います。

# サンプルコードリポジトリ

https://github.com/hito-psv/cognito-demo-001