Amplify + Cognitoでユーザ登録画面とユーザ認証までを試してみた

2021.03.20

Amplify + Cognitoで調べるとよく目にするオレンジ色のユーザ登録画面からCognitoへユーザ登録ってどうやってるのか気になったので手を動かしてみました。

今回取り扱う内容のWorkshopはこちらです。当記事で試した範囲は環境構築からはじめても1時間もあれば終わります。

ゴールはよく見かけるユーザ登録画面の作成し、Congitoのユーザ登録・認証を試したいだけです。初歩の初歩と思われる部分です。思いの外Amplifyでの認証情報の取り扱いでハマったのでブログに残しておきます。

できたこと

  • Amplifyの環境構築
  • ユーザ登録画面の作成
  • ユーザ登録画面からCognitoにユーザ登録・認証

AMPLIFY SNS WORKSHOP

Amplify SNS Workshopへようこそ!本ワークショップではTwitterライクなソーシャルメディアアプリケーションの開発を通して、実践的に AWS Amplify について学ぶことが出来ます。

3章の「MVPを作ろう!」まで進めるとCognitoのユーザ認証機能を試せるのでそこまで進めます。

前提条件

Amplifyの実行環境は一切ないため必要なコマンドのインストールからはじめます。普段フロントエンドに触れないので知識もないです。

前提条件 :: Amplify SNS Workshop

Node.jsのインストール

$ brew install nodejs

$ node -v
v15.11.0

$ npm -v
7.6.0

Amplify CLIのインストール

$ npm install -g @aws-amplify/cli

$ amplify version
4.45.2

Workshopの説明ではJavaのインストールもしています。Cognitoのユーザ登録・認証を試すまでには必要ありませんでした。したがってJavaはインストールはしていません。

MVPを作ろう!

MVPを作ろう! :: Amplify SNS Workshop

作業ディレクトリ作成

$ mkdir amplify-sns-workshop
$ cd amplify-sns-workshop
$ npx create-react-app boyaki
$ cd boyaki

Amplifyの初期化

インタラクティブ形式で質問に答えていきます。ここでハマったので後ほどプロファイルの設定内容に触れます。

$ amplify init

ほぼデフォルト値です。参考までに入力した内容は下記になります。

プロファイル名の項目は各環境によって異なります。私のmyaccountプロファイルはMFA認証が必要なため、トークンコードの入力を最後に求められています。

  • ? Enter a name for the project boyaki
  • ? Enter a name for the environment production
  • ? Choose your default editor: Visual Studio Code
  • ? Choose the type of app that you're building javascript
  • Please tell us about your project
  • ? What javascript framework are you using react
  • ? Source Directory Path: src
  • ? Distribution Directory Path: build
  • ? Build Command: npm run-script build
  • ? Start Command: npm run-script start
  • Using default provider awscloudformation
  • ? Select the authentication method you want to use: AWS profile
  • ? Please choose the profile you want to use myaccount
  • Profile myaccount is configured to assume role
  • arn:aws:iam::00000000000:role/cm-ohmura.yasutaka
  • It requires MFA authentication. The MFA device is
  • arn:aws:iam::1111111111:mfa/cm-ohmura.yasutaka
  • ? Enter the MFA token code: 999999

amplify init ができなくて苦戦

普段はアカウントA(メインアカウント)からアカウントB(検証用アカウント)へMFA付きのスイッチロールしてアクセスしています。下記ブログで紹介されているイメージです。

当初、amplify init 実行時にプロファイル指定ではなく アクセスキー指定 にしました。プロファイルにはメインアカウントの情報しかありませんでした。リソースをデプロイしたい検証用アカウント用のプロファイルはありません。

amplify initiを実行しスイッチロールして得た一時的な認証情報のアクセスキーと、シークレットキーを入力しました。

amplify init

? Select the authentication method you want to use:
  AWS profile
❯ AWS access keys

? accessKeyId:  ***
? secretAccessKey:  ***

下記のエラーによりamplify initは失敗します。

Error Message

UnrecognizedClientException: The security token included in the request is invalid.

トークンも入力したいのですがamplify initはアクセスキー(accessKeyId)と、シークレットキー(secretAccessKey)の入力しか聞いてきません。スイッチロールで得た認証情報をアクセスキー指定で入力してもamplify initを実行できないことを悟ります。

解決方法

AWS認証情報にスイッチロール先のプロファイルを作成。[profile myaccount]の部分を新規に追加しました。

config

[default]
region = us-east-1
output = json

[profile myaccount]
role_arn = arn:aws:iam::00000000000:role/cm-ohmura.yasutaka # メインアカウント
mfa_serial = arn:aws:iam::11111111111:mfa/cm-ohmura.yasutaka # スイッチロール先のアカウント
source_profile = default

credentialsには手を加えずそのままです。メインアカウントのアクセスキー情報のみ設定してあります。

credentials

[default]
aws_access_key_id = xxx
aws_secret_access_key = xxx

プロファイル追加後のconfigの設定内容でamplify init実行時にAWS profileを選択し、プロファイル名を入力すると認証問題は解決できました。

? Select the authentication method you want to use: AWS profile
? Please choose the profile you want to use myaccount

環境のテスト

Workshopの内容に戻ります。

$ npm start

WBブランチからhttp://localhost:3000にアクセスし下記の画面を確認できます。

認証機能

認証機能 :: Amplify SNS Workshop

認証機能の追加

$ amplify add auth
Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito.

 Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections.
 How do you want users to be able to sign in? Username
 Do you want to configure advanced settings? No, I am done.
$ amplify status

Current Environment: production

| Category | Resource name  | Operation | Provider plugin   |
| -------- | -------------- | --------- | ----------------- |
| Auth     | boyaki0a7413bb | Create    | awscloudformation |
$ amplify push
✔ Successfully pulled backend environment production from the cloud.

Current Environment: production

| Category | Resource name  | Operation | Provider plugin   |
| -------- | -------------- | --------- | ----------------- |
| Auth     | boyaki0a7413bb | Create    | awscloudformation |
? Are you sure you want to continue? Yes

--- 省略 ---

✔ All resources are updated in the cloud

マネジメントコンソールからCognitoを確認するとユーザプールが追加されています。

認証機能のフロントエンドへの実装

aws-amplifyとAmplify Frameworkをアプリケーションに追加します。

npm install --save aws-amplify@ @aws-amplify/ui-react@

./src/App.jsファイルの中身を全削除して下記の内容をコピペして置き換えます。これがよく見かけるオレンジ色の画面の正体でした。

import React from 'react';
import Amplify from 'aws-amplify';
import { AmplifyAuthenticator, AmplifySignUp, AmplifySignOut } from '@aws-amplify/ui-react';
import { AuthState, onAuthUIStateChange } from '@aws-amplify/ui-components';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);

const App = () => {
    const [authState, setAuthState] = React.useState();
    const [user, setUser] = React.useState();

    React.useEffect(() => {
        return onAuthUIStateChange((nextAuthState, authData) => {
            setAuthState(nextAuthState);
            setUser(authData)
        });
    }, []);

  return authState === AuthState.SignedIn && user ? (
      <div className="App">
          <div>Hello, {user.username}</div>
          <AmplifySignOut />
      </div>
    ) : (
      <AmplifyAuthenticator>
        <AmplifySignUp
          slot="sign-up"
          formFields={[
            { type: "username" },
            { type: "password" },
            { type: "email" }
          ]}
        />
      </AmplifyAuthenticator>
  );
}

export default App;

WBブランチからhttp://localhost:3000にアクセスし念願の画面を確認できました。

新規ユーザ登録。

確認画面が表示されました。

メールを確認すると確認コードが届いています。

メールに記載のコードを入力します。

ログインに成功画面。

Cognitoのユーザプール画面から確認。ユーザが追加されています。

追加で新規ユーザ登録後、自己サインアップが終わっていない状態。メール認証が済んでいないこともダッシュボードから確認できます。

後片付け

ユーザ登録画面と、ユーザ登録するだけの目的は達したので作成したリソースを削除します。amplify deleteコマンドでお片付け。

$ amplify delete
? Are you sure you want to continue? This CANNOT be undone. (This will delete all the environments of the project from the clou
d and wipe out all the local files created by Amplify CLI) Yes
⠋ Deleting resources from the cloud. This may take a few minutes...
Deleting env:production
✔ Project deleted in the cloud
Project deleted locally.

ユーザプールは削除されました。

おわりに

CognitoはAWS Developer Associate試験、AWS DevOps Engineer Professional試験で多少は勉強しました。しかし、学習の過程でCognitoについて手を動かすことはしませんでした。 試してみてわかったのは1時間もあればよく見る画面からCognitoにユーザ登録をできることです。途中Amplifyの認証にハマった部分を除けばですが。

試験勉強で「Cognitoいまいちイメージわかないんだよなぁ、一回くらい触っておいたほうがいいかなー」と思っている方は休日にちょっと手を動かしてみてはいかがでしょうか。