1
0

Cognito + React でメアド検証を行い、ユーザーを登録する

Posted at

はじめに

cognitoを使ってユーザー管理をしたい!と思ったのでreactと組み合わせて実装してみます。

Cognitoユーザープールを作成する

Cognitoユーザープールを作成します。

cap01.PNG

参考:

ユーザープール作成 ステップ1

サインインオプションを指定します。
今回はEメールアドレスとパスワードで認証したいので、
ここではEメールを指定しておきます。

cap02.PNG

次へをクリックし、進みます。

ユーザープール作成 ステップ2

セキュリティ要件を設定します。

パスワードポリシーはデフォルトのままにします。

cap03.PNG

テストなので、MFAはなしにしておきます。

cap04.PNG

次へをクリックし、進みます。

ユーザープール作成 ステップ3

サインアップ処理の挙動を設定します。
フロントエンドから認可なしでサインアップ関数を実行するため、自己登録を有効化しておきます。

cap05.PNG

サインアップ時に検証メッセージを自動送信する設定を有効化しておきます。
無効にした場合、lambda、SESなどで自前実装できます。

cap06.PNG

その他の設定はデフォルトのままにしておきます。

cap07.PNG

次へをクリックし、進みます。

ユーザープール作成 ステップ4

ステップ3で有効化した検証メッセージの送信方法を設定します。
テストなので、簡単なSESを使用しない設定にします。

cap08.PNG

その他の設定はデフォルトのままにしておきます。
次へをクリックし、進みます。

ユーザープール作成 ステップ5

ユーザープールの設定を行います。
名前とホストされた認証ページを用意するかを選択します。
認証ページはreactで作成するので、チェックを外します。

cap09.PNG

今回のreactアプリ用のアプリケーションクライアントを設定します。

スイッチロールのようなイメージで、アプリケーションクライアントを複数用意することで、ユーザープール内のユーザーに対し、複数の認証フローやOpenID Connect のスコープを指定することができます。

クライアント名を指定します。

cap10.PNG

テストなのでクライアントシークレットは不要としておきます。

※参考

認証フローはデフォルトのままとしておきます。

cap11.PNG

cap12.PNG

次へをクリックし、進みます。

ユーザープール作成 ステップ6

cap13.PNG

cap14.PNG

問題なければ、ユーザープールを作成します。

ユーザープールIDとアプリケーションクライアントIDを取得する

アプリで使用するので、ユーザープールIDとアプリケーションクライアントIDを取得します。

マネジメントコンソールから取得します。

cap15.PNG

アプリケーションクライアントのクライアントIDも同様に取得します。

cap16.PNG

cap17.PNG

Cognitoの初期設定はここまでで完了です。

必要なライブラリのインポート

reactプロジェクトの用意

npx create-react-app react-cognito --template typescript

必要なライブラリのインポート

aws amplifyライブラリが必要なのでインポートします。
※amplify appは作成せず、関数だけ利用します。

npm i aws-amplify

実装後の認証フローを整理する

アプリは以下のドキュメントのフローでユーザーを作成・確認します。

  1. ユーザーは、アプリで作成した [Create an account] (アカウントを作成) ボタンを選択します。E メールアドレスとパスワードを入力します。
  2. アプリケーションは SignUp API リクエストを送信し、ユーザープールに新しいユーザーを作成します。
  3. アプリケーションは、ユーザーに E メールの確認コードを求めます。ユーザーは、E メールメッセージで受け取ったコードを入力します。
  4. アプリは、ユーザーの確認コードを含む ConfirmSignUp API リクエストを送信します。

早速コードを準備してテストしてみます!!

reactコードを準備してテストする

index.tsxに以下のコードを追加し、Cognito ユーザープールへの接続設定を行います。

src/index.tsx
// 追加コードここから
import { Amplify } from 'aws-amplify';

Amplify.configure({
  Auth: {
    Cognito: {
      userPoolId: process.env.REACT_APP_USER_POOL_ID!,
      userPoolClientId: process.env.REACT_APP_USER_POOL_CLIENT_ID!,
    }
  }
})
// 追加コードここまで

// ここからデフォルトのindex.tsx
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

また、以下のコードをsrcに追加し、テスト用ページを表示します。

test.tsx
import React, { useState } from 'react';
import { signUp, confirmSignUp, signIn, getCurrentUser, signOut } from 'aws-amplify/auth';

const Test: React.FC = () => {

    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [confirmationCode, setConfirmationCode] = useState('');

    const handleSignUp = async () => {
        // signUp関数を使用する。
        // アカウントはUnconfirmed状態作成され、別途有効化する必要がある。
        const output = await signUp({
            username: email,
            password,
        })
        console.log(output)
    };

    const handleVerify = async () => {
        // 入力されたコードを検証し、ユーザーの有効化を行う
        const output = await confirmSignUp({
            username: email,
            confirmationCode,
        })
        console.log(output)
    };

    const handleLogin = async () => {
        // 入力されたemail, passwordを使用し、ユーザーのログイン処理を行う
        await signIn({
            username: email,
            password,
        })

        const output = await getCurrentUser()
        console.log(output)
    }

    const handleLogout = async () => {
        await signOut()
    }

    return (
        <div className="App" style={{ maxWidth: "900px", margin: "auto", padding: "10px 50px" }}>
            <h1>Cognito Test</h1>
            <h2>SignUp</h2>
            <div>
                <label htmlFor="email">登録メールアドレス</label>
                <input
                    id="email"
                    type="text"
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                />
            </div>
            <div>
                <label htmlFor="password">パスワード</label>
                <input
                    id="password"
                    type="text"
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                />
            </div>
            <div>
                <button onClick={handleSignUp}>検証用コードをメールアドレスに送信する</button>
            </div>
            <h2>VerifyUser</h2>
            <div>
                <label htmlFor="confirmationCode">検証コード</label>
                <input
                    id="confirmationCode"
                    type="text"
                    value={confirmationCode}
                    onChange={(e) => setConfirmationCode(e.target.value)}
                />
            </div>
            <div>
                <button onClick={handleVerify}>コードを検証する</button>
            </div>
            <h2>Login/Logout</h2>
            <div>
                <button onClick={handleLogin}>ログインする</button>
            </div>
            <div>
                <button onClick={handleLogout}>ログアウトする</button>
            </div>
        </div>
    );
};

export default Test;

コード解説

signUp関数

フロントエンドのクライアントに、ユーザープールへの登録をさせるメソッドです。
signUp関数は上記したフローのステップ2を実行します。

  1. アプリケーションは SignUp API リクエストを送信し、ユーザープールに新しいユーザーを作成します。

※参考:詳しいドキュメント

confirmSignUp関数

confirmSignUp関数は上記したフローのステップ4を実行します。
今回は、クライアントにメールを確認してもらい、メール内にあるコードを受け取り、リクエストボディとしてます。

アプリは、ユーザーの確認コードを含む ConfirmSignUp API リクエストを送信します。

※参考:詳しいドキュメント

signIn関数

そのままの関数です。

※参考:詳しいドキュメント

getCurrentUser関数

signIn状態の場合、ユーザー情報を取得できます。
今回はテスト用に実行します。

※参考:詳しいドキュメント

テスト

作成したテストページで動作をテストします。

cap18.PNG

SignUpしてみる

メールアドレスとパスワードを入力し、SignUp関数を実行します。

cap19.PNG

関数の戻り値をコンソールに出力しています。

cap20.PNG

SignUpが完了していないことや、Confirmが必要なことがわかります。

Cognitoユーザープールに保存されているユーザー情報も確認してみます。

cap20_1.PNG

ユーザーが登録できてます!!!
ただ、確認ステータスが未確認なことがわかります。

メーラーを確認します。

cap21.PNG

検証コードが送信されていることがわかります。

Confirmしてみる

メールされた検証コードを使用し、SignUpを完了してみます。
入力した検証コードとemailでconfirmSignUp関数を実行します。

cap22.PNG

関数の戻り値をコンソールに出力しています。

cap23.PNG

SignUpが完了していそうです!!

Cognitoユーザープールに保存されているユーザー情報も確認してみます。

cap24.PNG

確認ステータスが確認になっていることがわかります!!!!

SignInしてみる

SignIn関数とgetCurrentUser関数を実行してみます。

cap25.PNG

エラーも出ず、ユーザー情報が取れました!!!

おわりに

CognitoとReactでユーザーのサインアップ~ログインまで動作確認しました。
Cognitoは複雑なイメージがあったのですが、簡単に疎通させることができました!!

メールに認証用リンクを乗せて、リンクを踏むだけで検証完了とするつくりを目指したいので、次はその仕組みを考えようかなと思います!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0