BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【AWS】【Cognito】アカウントステータスがFORCE_CHANGE_PASSWORDになる問題を解決する

はじめに

こんにちは、株式会社BFT新人エンジニアのないとうです。
先日AWS Cognitoでテストユーザーを作成したとき、画像のようにアカウントステータスが
【FORCE_CHANGE_PASSWORD】となる問題が発生しました。
f:id:bftnagoya:20210819102440p:plain AWSコンソール上ではアカウントステータスを変更することができなかったので、
他の方法でこの問題を解決しなければなりません。
そこで、同じ問題が発生した人の参考になるように今回とった方法を紹介します。

AWS CLIを使う方法(失敗)

調べてみてすぐに出てきた方法がこのCLIを使う方法でした。
CLIをPCにインストールして実行する方法ですが、CLIを使うために【AWS Access Key ID】と【AWS Secret Access Key】が必要になります。
この二つのKeyを入手するには、AWS IAMにあるユーザーからアクセスキーを作成する必要があるのですが、私のアカウントには権限が足りないようでした。
f:id:bftnagoya:20210819112027p:plain 単純に権限を追加すればいいだろうと言われればそれまでですが、最低限の権限で行っていきたいと考えているので別の方法を考えることにしました。

ユーザー作成、認証画面を作成する方法

アクセスキーの作成ができなかったので、コンソールでユーザーを作るのはあきらめてシステムとしてユーザーの作成、認証を行うシステムの作成を行うこととしました。

実装環境

今回はLightsailでNode.jsのインストールされたインスタンスを作成し、そこにVue.jsをインストールしシステムを作成しました。
それぞれバージョンは
Node.js : 12.22.3
Vue.js : 4.5.13

ユーザー作成画面

Vue.jsのプロジェクトを作成し、そこにsrc/pages/users.vueとしてページを作成して実装していきます。 users.vueの中身は以下のようになります。

<template>
  <div class="signup">
    <h2>ユーザー登録</h2>
    <form @submit.prevent="signup">
      <div>
        メール:
        <input type="text" placeholder="メール" v-model="username" required>
      </div>
      <div>
        パスワード:
        <input type="password" placeholder="パスワード" v-model="password" required>
      </div>
      <div>
        パスワード(確認):
        <input type="password" placeholder="パスワード(確認)" v-model="password" required>
      </div>
      <button>登録</button>
    </form>
  </div>
</template>

<style lang="scss">
</style>

<script>
  import {
    CognitoUserPool,
    CognitoUserAttribute
  } from 'amazon-cognito-identity-js'



  export default {
    name: 'Signup',
    data () {
      return {
        username: '',
        password: '',
        passwordConfirm: ''
      }
    },
    methods:{
      signup(){
       var poolData = {
         UserPoolId: 'ap-northeast-1_xxxxxxxx',
         ClientId: 'yyyyyyyyyyyyyyyyyyyyyyyyy',
       };
       var userPool = new CognitoUserPool(poolData);
       var username = this.username;
       var password = this.password;
       var confirm = this.passwordConfirm;

       const dataEmail = { Name: 'email', Value: username };
       const attributeList = [];
       attributeList.push(new CognitoUserAttribute(dataEmail));

       if(password==confirm){

       userPool.signUp(username, password, attributeList, null, function(
           err,
           result
       ) {
           if (err) {
             alert('エラー'+err.message || JSON.stringify(err));
             return;
           }
           var cognitoUser = result.user;
           console.log('user name is ' + cognitoUser.getUsername());
           alert("ユーザーの作成に成功しました");
           location.assign('認証ページurl');
       });
       }else{alert("異なるパスワードが入力されています");}
      }
    }
  }

</script>

画面としてはメールアドレスとパスワードを入力して登録するものになっています。
f:id:bftnagoya:20210819125101p:plain 実行したところ、Cognitoのコンソール上にユーザーを作成することができました。
f:id:bftnagoya:20210819140155p:plain ただしこの状態だとメールアドレス認証が必要なので認証画面も作成していきます。

ユーザー認証画面

src/pages/confirm.vueとしてページを作成して実装していきます。
表示するためにはルーティングの設定が必要ですが今回は省略します。
confirm.vueの中身は以下のようになります。

<template>
  <div class="confirm">
    <h2>確認コード入力</h2>
    <form @submit.prevent="confirm">
      <div>
        メール:
        <input type="text" placeholder="メール" v-model="username" required>
      </div>
      <div>
        パスワード:
        <input type="text" placeholder="確認コード" v-model="confirmationCode" required>
      </div>
      <button>確認</button>
    </form>
  </div>
</template>

<script>
  import {
    CognitoUserPool,
    CognitoUser
  } from 'amazon-cognito-identity-js'


  export default {
    name: 'Confirm',
    data () {
      return {
        username: '',
        confirmationCode: ''
      }
    },
 methods: {
      confirm () {
        var poolData = {
          UserPoolId: 'ap-northeast-1_xxxxxxxx', // Your user pool id here
          ClientId: 'yyyyyyyyyyyyyyyyyyyyyyyyy', // Your client id here
        };
        var userPool = new CognitoUserPool(poolData);

        var username = this.username;
        var code = this.confirmationCode;

        var userData = {
          Username: username,
          Pool: userPool,
        };

        var cognitoUser = new CognitoUser(userData);
        cognitoUser.confirmRegistration(code, true, function(err, result) {
          if (err) {
            alert('エラー:'+err.message || JSON.stringify(err));
            return;
          }
          console.log('call result: ' + result);
          alert("認証完了しました");
        });
      }
    }
  }
</script>

画面としてはメールアドレスと認証コードを入力して認証するものになっています。
f:id:bftnagoya:20210819135753p:plain
実行したところユーザーのメールアドレスの認証が行われました。
f:id:bftnagoya:20210819140430p:plain

おわりに

今回はCognitoでのユーザー作成方法を考えてみました。
私はこれで解決することができましたが、他にも方法はあると思います。
もっと楽に解決することがないか調査してみたいと思います。
それでは。

参照

AWS CLIを使ってCognitoユーザーステータスのFORCE_CHANGE_PASSWORDをCONFIRMEDにしてみる | DevelopersIO

vue-cliで作成したSPAにシンプルにCognitoログインを組み込む - Qiita

Amazon Cognitoを使ってシンプルなログイン画面を作ってみる - Qiita