Nanolier

CognitoのユーザープールとIDプールの違いについて

2022/08/02

Cognitoの設定をする際になんとなくユーザープールとIDプールを設定していましたが、それぞれの違いを確認した結果、利用用途によってはIDプールが不要かもという結論になりました。

下記の記事に解説が書いてました。
Amazon Cognito のユーザープールと ID プールの違いは何ですか?

ユーザープールの使用用途

  • アプリケーションでのユーザーの認証に使用 (アイパス、MFAなど)
  • ユーザー情報の管理
  • カスタム認証フローの使用

ユーザープールは認証に使用するためのものでした。

IDプールの使用用途

  • CognitoにログインしているユーザーがAWSのS3などのリソースを利用する
  • 未認証ユーザー用の AWS 認証情報を一時的に生成する。

IDプールはログインしているユーザーがAWSのリソースにアクセスする際に利用するもののようです。

未認証ユーザー用のAWS認証情報を一時的に生成することで、未認証ユーザーでもAWSのリソースを利用することができるようです。

認証のみの場合はユーザープールだけでよさそう

クライアントサイドでログインし、AWSのリソースにはバックエンドからアクセスする場合、IDプールは不要な気がします。
実際に、IDプールの設定をせずとも、クライアントサイドからのログイン等の処理は問題なく実行可能でした。

実装サンプル

最後にTypeScriptで実装したサンプルを置いておきます。

import {
  CognitoUserPool,
  CognitoUser,
  CognitoUserAttribute,
  CognitoUserSession,
  AuthenticationDetails,
  ISignUpResult,
} from 'amazon-cognito-identity-js';

type LoginResult = {
  idToken: string;
  accessToken: string;
};

type GetCurrentUserResult = {
  user: CognitoUser;
  idToken: string;
  accessToken: string;
};

class AuthService {
  cognitoUserPoll = new CognitoUserPool({
    UserPoolId: '{userPoolId}',
    ClientId: '{clientId}',
  });

  register(email: string, password: string) {
    const attributes = [
      new CognitoUserAttribute({
        Name: 'email',
        Value: email,
      }),
    ];

    return new Promise<ISignUpResult>((resolve, reject) => {
      this.cognitoUserPoll.signUp(
        email,
        password,
        attributes,
        [],
        (error, result) => {
          if (result) {
            resolve(result);
          } else {
            reject(error || new Error('resultが返って来ませんでした'));
          }
        }
      );
    });
  }

  login(email: string, password: string) {
    const authenticationDetails = new AuthenticationDetails({
      Username: email,
      Password: password,
    });
    const cognitoUser = new CognitoUser({
      Username: email,
      Pool: this.cognitoUserPoll,
    });

    return new Promise<LoginResult>((resolve, reject) => {
      cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: (result) => {
          resolve({
            accessToken: result.getAccessToken().getJwtToken(),
            idToken: result.getIdToken().getJwtToken(),
          });
        },
        onFailure: (error) => {
          reject(error);
        },
      });
    });
  }

  logout() {
    const user = this.cognitoUserPoll.getCurrentUser();
    user && user.signOut();
  }

  getCurrentUser() {
    const user = this.cognitoUserPoll.getCurrentUser();

    return new Promise<GetCurrentUserResult>((resolve, reject) => {
      if (user) {
        user.getSession(
          (error: Error | null, session: CognitoUserSession | null) => {
            error && reject(error);
            session &&
              resolve({
                user,
                idToken: session.getIdToken().getJwtToken(),
                accessToken: session.getAccessToken().getJwtToken(),
              });
          }
        );
      } else {
        reject(new Error('ユーザー情報が見つかりませんでした'));
      }
    });
  }
}

export default AuthService;

こちらの実装で問題なくログインが可能でした。
以上となります。お疲れ様でした。