Amazon cognito カスタム属性を利用したユーザー登録　～CSVファイルから登録～

今回の記事では
**「Amazon cognitoでユーザープールのカスタム属性を利用した場合のユーザー登録」**
に焦点を当てながらまとめていききます。

まず、Amazon Cognitoとは、AWSのサイトには以下のような説明があります。
>ウェブアプリケーションおよびモバイルアプリに素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加できます。出典：https://aws.amazon.com/jp/cognito/

要するに、サインインなどのログイン機能を提供してくれるサービスととらえておけばOKです。Amazon Cognitoでは「ユーザープール」と「IDプール」の2つのプールがあります。前者はユーザー登録に使用でき、後者はIDフェデレーションに利用できます。

今回は「ユーザープール」（ユーザー登録）を取り上げます。

#やりたいこと
やりたいことは**Amazon Cognitoを利用したユーザー登録**です。
さらに、以下の要件が加わります。
**・CSV形式ファイルを取り込んでユーザーを作成すること
　（CSV形式ファイルにはユーザ情報が記載されている）
・ユーザー情報として以下の属性を持っていること**

```
①メールアドレス
②名前
③電話番号
④ふりがな
⑤ユーザータイプ（一般ユーザー、運営ユーザーなど）
```

Amazon Cognitoでは、デフォルトで用意されている「標準属性」と自由に設定できる「カスタム属性が」あり、ユーザーの属性として扱うことができます。上記属性のうち、「①メールアドレス」「②名前」「③電話番号」は標準属性に含まれています。ので、用意されているもの（標準属性）を使用できます。しかし、「④ふりがな」「⑤ユーザータイプ」は標準属性に含まれていません。

ちなみに、標準属性はこちらを[参照](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-settings-attributes.html#cognito-user-pools-standard-attributes)してください。

ので、「④ふりがな」「⑤ユーザータイプ」はカスタム属性として作成することが必要です。**が、このカスタム属性が曲者でした。
Amazon Cognitoのコンソール画面にCSV形式ファイルを取り込める機能があります。しかし、標準属性のみであれば、コンソール画面からcsvファイルを取り込めるようですが、カスタム属性を取り込むことができないようでした。**ので、取り込み用のバッチを作成することにしました。

では、**①ユーザープールの作成、②バッチの作成の2つの流れで、カスタム属性を含むユーザー属性をcsvファイルでAmazon Cognitoにユーザー登録する方法を見ていきましょう。**

なお、以下スクショは2021年12月16日に作成しました。
画面デザインや設定項目が変わる可能性がありますので、ご留意ください。

#①ユーザープールの作成
1.Amazon Cognitoの画面で「ユーザープールの管理」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/de5d3515-7cc0-5889-6853-868af91ebe5b.png)

2.「ユーザープールを作成する」を押下します。
![cognito2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/beeebaec-61f4-598d-a77f-88d1e460fe3b.png)

3.プール名を入力します。ここでは「sample」と入力しました。さらに、「ステップに従って設定する」を押下します。
![cognito3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/14b1bfcd-4879-fd6f-3f01-0dc45bbfc04e.png)

4.各設定を行います。（スクショの都合で1ページをスクショ3枚に分けました）

「Eメールアドレスおよび電話番号」を選択し、「Eメールアドレスを許可」を選択します。
こうすると、サインインする際に「Eメールアドレス」が「ユーザーID」となります。
![cognito4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/8a0a898c-b787-3f69-e65b-23da56fda74d.png)

標準属性を選択します。「①メールアドレス ②名前 ③電話番号」が要件なので、「email」「name」「phone number」を選択します。
![cognito5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/3c2d310e-42bc-c88d-0262-cd5a99f44741.png)

カスタム属性を選択します。今回は「④ふりがな ⑤ユーザータイプ」です。
「別の属性の追加」を押下し、タイプを「string」とし、名前を「name_hurikana」と入力し、最小長を「1」最大長を「256」とします。変更可能にチェックを入れておきましょう。
次に、タイプを「number」とし、名前を「user_type」と入力し、最小値を「0」最大値を「10」とします。変更可能にチェックを入れておきましょう。
入力、選択ができたら、「次のステップ」を押下します。
![cognito6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/56f6a7f8-d919-907c-1489-50bd5e37b730.png)

5.各設定を行います。
今回は↓スクショのように設定しました。入力、選択ができたら、「次のステップ」を押下します。
![cognito7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/dec82034-184f-edb9-074a-989a40781cec.png)

6.各設定を行います。（スクショの都合で1ページをスクショ2枚に分けました）
今回は↓スクショのように設定しました。入力、選択ができたら、「次のステップ」を押下します。
![cognito8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/50a9898c-b0ac-1e2c-403f-5cc8ad6951e8.png)

![cognito9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/f38b0907-371f-00f0-b248-f3712c16bbc6.png)
画像にある「新規ロール名」はデフォルトのものです。

7.Eメールアドレスをカスタマイズします。入力ができたら、「次のステップ」を押下します。（スクショの都合で1ページをスクショ3枚に分けました）

↓今回はスルーしました。
![cognito10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/d9fd1218-d360-d4d2-a0fe-d217ab3d2d35.png)

↓今回はSESと連携していないので、「Amazon SES設定を通じてEメールを送信しますか」の項目では、「いいえ」を選んでいます。cognitoの機能で送れるメール数には上限があるようです。SES設定を行うことでメールの配信数を増やすことができます。SESと連携させる場合は、ここで「はい」を選択します。

また、「Eメール検証メッセージをカスタマイズしますか？」
を入力すると、ユーザーに「検証コード」を送信するメールの件名と本文を任意の文面にすることができます。

![cognito11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/650b29f6-6131-fb84-2643-7fde8950b791.png)
↓「ユーザー招待メッセージをカスタマイズしますか？」
を入力すると、ユーザーを登録した際に送信されるメールの件名と本文を任意の文面にすることができます。
![cognito12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/76528ce9-62c1-1ce7-e0b6-50907ae9875d.png)

8.ここ↓はスルーしました！「次のステップ」を押下します。
![cognito13.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/05402d76-3f86-d804-d4f8-2ffb64f338ae.png)

9.「いいえ」を選択します。選択ができたら、「次のステップ」を押下します。
![cognito14.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/13d9261f-e44e-9718-ba0d-3900231909fc.png)

10.ここ↓はスルーしました！「次のステップ」を押下します。
![cognito15.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/cb6f34b8-48da-9d56-61e2-1a0ea7fee077.png)


11.ここ↓はスルーしました！「次のステップ」を押下します。
![cognito16.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/131487f9-6e74-421d-78b3-b79d7aabbbc9.png)

12.確認ページです。「プールを作成」を押下します。
これでユーザープールの作成はできました。
![cognito17.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/73526e94-14d7-c580-1a84-e7d6a34e70e5.png)


#②バッチの作成
ユーザープールができましたので、カスタム属性を含むユーザー属性をAmazon Cognitoに取り込んでいきましょう！CSV形式ファイルはs3にアップします。ので、バッチはs3からCSV形式ファイルを持ってきて取り込む必要があります。
おおまかな処理の流れは以下の通りです。

**①s3からCSV形式ファイルを移動
②CSV形式ファイルからデータの抽出
③ユーザー登録
④パスワード設定**

また、以下のような内容のCSVファイルをAmazon cognitoに取り込む想定です。画像はCSVファイルをExcelで開いたもので、2件のユーザー情報が記載されています。（文字化けにも注意しましょう）
このCSVファイルをS3の任意の場所にアップロードしましょう。

![cognito19.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/4c446c03-98ad-5f7d-5986-3c116e1303fe.png)

そして、バッチの内容はこちらです！shellscriptで作成しております。

```bash:userCreate.sh
#!/bin/sh

#ファイル名取得
file_name=`aws s3 ls (s3の格納場所のパス)/ | sort -nr | head -n 1 | awk '{print $NF}'`

#S3からCSV形式ファイルを移動（コピー）
aws s3 cp (s3の格納場所のパス)/${file_name} （実行サーバー上パス）/${file_name}

#カウンター
COUNTER=0

#大文字小文字数字記号を含む15桁のランダム文字列を生成
pass=`cat /dev/urandom | base64 | fold -w 15 | head -n 1`$((RANDOM%+10))

#特定のデータの抽出
while read row; do
    if [ ${COUNTER} != 0 ]; then
        name=`echo $row | cut -d , -f 1`
        email=`echo $row | cut -d , -f 2`
        phone_number=`echo $row | cut -d , -f 3`
        name_hurikana=`echo $row | cut -d , -f 4`
        user_type=`echo $row | cut -d , -f 5`

        #1行分の情報を取る
        row_info=`echo $row`

        #電話番号の頭に+がない場合追加
        if ["`echo $phone_number | grep '+'`" = ""];then
            phone_number=+81$phone_number
        fi

        #csvから取得したデータでユーザ登録
        aws cognito-idp admin-create-user \
        --user-pool-id (ユーザープールID) \
        --username $email \
        --user-attributes Name=email,Value=$email \
        Name=name,Value=$name \
        Name=email_verified,Value=TRUE \
        Name=phone_number,Value=$phone_number \
        Name=phone_number_verified,Value=TRUE \
        Name=custom:name_hurikana,Value=$name_hurikana \
        Name=custom:user_type,Value=$user_type \
        --desired-delivery-mediums EMAIL

        #パスワード設定
        aws cognito-idp admin-set-user-password \
        --user-pool-id (ユーザープールID) \
        --username $email --password $pass --permanent
    fi

    COUNTER=` expr $COUNTER + 1`

done < （実行サーバー上パス）/$file_name

```

ポイントなのは、パスワード設定もバッチの中で行ってしまうことです。
「aws cognito-idp admin-create-user ～」コマンドを叩くと、ステータス（cognitoのコンソール画面で確認できます）が「FORCE_CHANGE_PASSWORD」となります。この状態ではユーザーがパスワードリセットすることができません。なので、パスワード設定のコマンドも叩く必要があります。（aws cognito-idp admin-set-user-password～のコマンドです。）このコマンドを叩くと、ステータスが「CONFIRMED」に変わります。そうして、画面からパスワードリセットをリクエストすると、検証コードが送信されます。

もう一つポイントがあります。電話番号の登録です。今回は電話番号をユーザー属性として設定しています。cognitoで設定する際には国際電話の形（日本であれば、+81で始まる電話番号）で設定することが必要です。よって、csvファイル内の電話番号に「（日本であれば、）+81」を付ける必要があります。ついていない場合は電話番号を正常に登録できません。CSVファイルでは、国際電話の形で記入していないので、↓の部分で、バッチの中で電話番号の形を整えています。

```
        #電話番号の頭に+がない場合追加
        if ["`echo $phone_number | grep '+'`" = ""];then
            phone_number=+81$phone_number
        fi
```

最後に、今回のバッチを用いて、ユーザー登録した場合の初回ログインまでの流れを確認しましょう。以下のような流れです。

![スライド1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/a4f15891-a1b4-d7c7-04ec-1419f7f89249.jpeg)

![スライド2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/9832711b-c101-dcfb-8d1a-f09c268dcba3.jpeg)

↓は画面イメージです。
![スライド3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605915/7640fccc-34f9-7eaa-0f05-99bbb661a144.jpeg)




***

カスタム属性をCSVファイルを用いて登録しようとしたところ、うまく登録ができず試行錯誤することになりました。カスタム属性を扱った記事が少なかったこともあるので、もしもこの記事が誰かの役に立ったら嬉しいです。

最後まで読んでいただいた方、ありがとうございました。

#参考文献
Amazon web service『AWS CLI command reference』（2021年12月22日利用）
https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/index.html#cli-aws-cognito-idp

AWS『ディベロッパーガイド　ユーザープールの属性の設定』（2021年12月22日利用）
https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-custom-attributes