AWS Amplify + React.js のシンプルなサンプル

AWS AmplifyとReact.jsを使うと、AWS上のアプリの認証・認可が簡単に実現できたので、簡単なサンプルを作ってみました。

https://aws.github.io/aws-amplify/media/quick_start
こちらにQuickStartがあるのですが、こちらのサンプルはAWS上のリソース作成を必要最低限にしたい場合の参考になればと思います。

このサンプルを実行するのに、最低限必要なものは以下のとおりです。

* node.js
* AWSのアカウント

# まずはReact.jsのアプリを作る

React.jsでは、[create-react-app](https://github.com/facebook/create-react-app)という、アプリを簡単に作り始められるツールがあるので、それを使います。

``` bash
$ npm install create-react-app
$ ./node_modules/.bin/create-react-app amplify-sample
$ cd amplify-sample
```

これで、`amplify-sample`というディレクトリでアプリを作る準備ができました。
試しに起動してみましょう。

``` bash
$ npm run start
```

Webブラウザが起動して、このようなページが表示されたでしょうか？

![](https://qiita-image-store.s3.amazonaws.com/0/117772/f0522a7d-7b40-ef3c-614a-569cdf53421c.png)

これでReact.jsのアプリの準備が完了です。

# AWS上にCognito UserPoolなどを作る

## Cognito UserPool

UserPoolをデフォルトから作成していきます。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/30c62e7e-3d19-8dcb-c5fa-f2774ef69428.png)

デフォルトの設定から、アプリクライアントを追加します。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/6c278402-0a65-1413-82c2-573238727401.png)

「クライアントシークレットを作成」のチェックボックスは外します。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/ee46867b-09b5-ad5b-1f8e-a39f3b8c69a7.png)

確認ページに戻り、UserPoolを作成します。


## Cognito Federated Identity

次に、フェデレーティッドアイデンティティからIDプールを作成します。

「認証されていないIDに〜」のチェックをONにします。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/cd2ba2d6-8934-6aa1-ff0d-83e6733b37e1.png)

まだプールの作成はしません。
「認証プロバイダー」から「Cognito」タブを選択して、UserPoolからの情報を設定して、IDプールを作成します。

「Your Cognito identities require access to your resources」のページで、認証済ユーザー用と未認証ユーザー用のRoleの作成の確認画面が表示されるので、デフォルトを受け入れて、2つのIAM Roleを作成します。

# アプリにAmplifyを組み込む

Amplifyをアプリに組み込んで、認証されるまでページが表示されないようにします。

``` bash
$ npm install --save aws-amplify
$ npm install --save aws-amplify-react
```

`src/App.js`を以下のように修正します。

`Amplify.configure()`のパラメーターには、これまで作成したUserPoolなどの値を設定します。


``` jsx:App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Amplify from 'aws-amplify';
import { withAuthenticator } from 'aws-amplify-react';

Amplify.configure({
    Auth: {
        identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab', 
        region: 'XX-XXXX-X', 
        userPoolId: 'XX-XXXX-X_abcd1234',
        userPoolWebClientId: 'XX-XXXX-X_abcd1234', 
    }
});

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default withAuthenticator(App);
```

ブラウザで表示すると、先程までのページから変わって、Sign Inのページが表示されます。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/38bdd079-7465-62b0-49a1-e48321d8cd32.png)

何が起こったのかというと、withAuthenticator()の中で、「認証されていれば、Appを表示」「認証されていなければ Sign Inページを表示」という制御をしています。

ちなみに、このSign Inのページは、Amplify（amplify-react）が提供しているものです。

# ユーザー登録２パターン

Cognito UserPoolでは、ユーザーの追加方法が２種類あります。

* ユーザーが自分でサインアップする
* 管理者がユーザーを登録する

ここでは、それぞれの追加方法を試してみます。

## ユーザーが自分でサインアップする

Sign Inページの「Sign Up」からサインアップして、ユーザーを登録してみます。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/058030b7-fbaf-7edf-e492-413cc73ae95d.png)

Sign Upページでメールアドレスを入力すると、そのアドレス宛に確認コードが届きます。
ここでのUsernameは、ログイン時のIDになるので、日本語などは使わない方が良いと思います。
試していませんが。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/cc0bbd88-48af-6322-3aa3-0687d5b83195.png)

確認コードを入力するとSignUpが完了します。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/0ac0bcc9-cd7b-b988-dc03-6b5f6fa08077.png)

SignUpが完了すると再び最初のページが表示されるので、自分で入力したパスワードでログインします。

UserPoolを見ると、無事にユーザーが登録されていました。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/88b364de-8066-1fe4-1b34-bf7f373e1bab.png)

ちなみに、ユーザーからの登録を受け付けたくない場合、UserPoolの設定で「ユーザーに自己サインアップを許可しますか?」の設定を変更することで実現できます。
ただし、amplify-reactで表示するSign Inページの「Sign Up」ボタンは消えないので、カスタマイズが必要になります。

## 管理者がユーザーを登録する

管理者がユーザーを登録することもできます。
この場合、

1. 管理者が仮パスワードをつけてユーザー作成
1. ユーザーが仮パスワードでログイン
1. ユーザーがパスワード変更

という手順になります。
Eメールを利用した確認コードでの登録は不要です。

ManagementConsoleからUser1ユーザーを登録すると、ステータスが`FORCE_CANGE_PASSWORD`の状態になっています。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/8446eb2c-4f09-a32f-a9fd-dd5044b115ef.png)

React.jsのSign Inページから、ユーザー名と、管理者が決めた仮パスワードを入力してSign Inします。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/958c1451-80a8-d844-2b3c-f9c191d9b8fb.png)

そうすると、パスワード変更ページが表示されるので、任意のパスワードを入力すると、パスワードが設定されて目的のページが表示されます。

UserPoolで確認すると、ステータスが「CONFIRMED」になっています。

![](https://qiita-image-store.s3.amazonaws.com/0/117772/7add5632-167e-81bc-1ccf-3f0faaca29e5.png)

# まとめ

React.jsで作ったアプリにAWS Amplifyを組み込むことで、簡単に認証の仕組みが使えるようになりました。
今後は、カスタマイズやIAM Roleでの細かいアクセス制御についても記事を書いていきたいと思います。