Next.jsを使ってAWS Cognitoユーザープールにサインアップ・サインインリクエストしてみる【その②】

# 前回の続き
[前回](https://qiita.com/ttf1998seiya/items/1934b6cb719062d30fa9)はサインアップリクエストまで行ったので、続きをしていきます

では早速いきましょう！

## サインアップだけではトークンを発行してくれない（っぽい）

私もこれは驚いたのですが、前回作ったサインアップリクエストだけでは、トークンを発行してくれないっぽいんですよね
なので、サインアップを実行後、サインインを実行してトークンを発行する必要があります

※前回で「new Promise」としていたのも、サインアップの実行が終わるまでサインインを行わせないためのものでした

作成したサインインの関数は以下になります

``` useAuth.ts
const login = (userName: string, password: string): Promise<LoginResponse> => 
{
    // サインインするユーザーのデータ
    // Usernameの部分は「Eメール」でもリクエストできるそうです
    const authenticationData = {
      Username: userName,
      Password: password,
    };

    const authenticationDetails = new AuthenticationDetails(authenticationData);

    const userPool = new CognitoUserPool(poolData);

    const userData = {
      Username: userName,
      Pool: userPool,
    };

    const cognitoUser = new CognitoUser(userData);

    return new Promise<LoginResponse>((resolve, reject) =>
      // 成功・失敗・パスワード確認ごとに実行する関数が変わる
      cognitoUser.authenticateUser(authenticationDetails, {
        // ログイン成功時に実行する関数
        onSuccess: (result) => {
        // idTokenというjwtを取得
          const idToken = result.getIdToken().getJwtToken();
          setCookie(null, ID_TOKEN_KEY, idToken);
          const successResponse: LoginResponse = {
            idToken,
            status: LOGIN_STATUS.SUCCESS,
          };
          // resolveに返す値は、Promiseの返り値
          resolve(successResponse);
        },
        onFailure: (err) => {
          // サインアップ後、ユーザープールに登録した、配信方法で届いた検証用コードでユーザーを検証していない場合はこのエラーになる
          // 私の場合は、確認ステータスを返却しています
          if (err.code === 'UserNotConfirmedException') {
            const confirmResponse: LoginResponse = {
              status: LOGIN_STATUS.CONFIRM,
            };
            resolve(confirmResponse);
            return;
          }
          // そのほかのエラーはrejectさせる
          console.error('err : ', err);
          const failureResponse: LoginResponse = {
            status: LOGIN_STATUS.FAILURE,
          };
          reject(failureResponse);
        },
      })
    );
  };
```

これを実行することで、ログインができますね

ただ、コード内のコメントにもあるように、サインアップ後はEメールに届いた確認コードを使用して、ユーザー確認が必要になります
そこで、その確認コードをリクエストする関数も作ってしまいます

``` useAuth.ts
const confirm = (
    userName: string,
    confirmationCode: string
  ): Promise<any> => {
    const userPool = new CognitoUserPool(poolData);

    const userData = {
      Username: userName,
      Pool: userPool,
    };

    const cognitoUser = new CognitoUser(userData);

    return new Promise<any>((resolve, reject) =>
      cognitoUser.confirmRegistration(
        confirmationCode,
        false,
        (err, result) => {
          if (err) {
            console.error('account err:', err);
            reject(err);
            return;
          }
          resolve(result);
        }
      )
    );
  };
```

これを実行することで、ユーザー確認ができますので、問題なければ成功してログインできます！

## おまけ
ログアウト関数も載せておきます(笑)
これは一瞬です

``` useAuth.ts
const logout = (): Promise<LogoutStatus> => {
    return new Promise<LogoutStatus>((resolve, reject) => {
      const userPool = new CognitoUserPool(poolData);
      const cognitoUser = userPool.getCurrentUser();
      if (cognitoUser !== null) {
        cognitoUser.signOut();
        destroyCookie(null, ID_TOKEN_KEY);
        resolve(LOGOUT_STATUS.SUCCESS);
      }
      reject(LOGOUT_STATUS.FAILURE);
    });
  };
```

## 終わりに
今回初めて実践したことだったのでわからないことが多く、もしかしたら不明な点が多々あるかもしれませんが、参考になれば幸いです！

間違っている点はぜひコメントいただけると幸いです！

ではまた！