このモジュールでは、アプリケーションで認証プロバイダーとして使用するために Amazon Cognito を設定します。Amazon Cognito は、ユーザーのサインアップ、検証、ログインなどを可能にする完全マネージド型の認証プロバイダーです。

Amazon Cognito には、ユーザープールID プールという 2 つの異なるコンポーネントがあります。ユーザープールは、ユーザーが Amazon Cognito またはサードパーティーの ID (Facebook など) 経由でサインインする標準ユーザーディレクトリです。認証に成功すると、ユーザーはアクセストークンや ID トークンなどのトークンを受け取ります。このトークンを使用して、バックエンドのリソースにアクセスできます。

対照的に、ID プールは、AWS リソースにアクセスするためにユーザーが一時的な AWS 認証情報を受信する方法を提供します。これを使用すると、AWS Lambda 関数、Amazon DynamoDB テーブル、またはその他のリソースへ制限されたアクセスが直接行えます。

このチュートリアルでは、Amazon Cognito ユーザープールを使用します。ユーザーがアプリケーションを介して登録できるようにします。登録後、クライアントを介してログインし、ID トークンを受け取ることができます。この ID トークンをヘッダーとしてアプリケーションに渡して、ユーザーを認証できます。

以下の手順では、Amazon Cognito ユーザープールを作成します。次に、ユーザープールにアクセスするクライアントを作成します。最後に、ユーザープールとやり取りするためのサンプルコードを見てみましょう。

モジュールの所要時間: 10 分


  • ステップ 1.Amazon Cognito ユーザープールを作成する

    user pool はユーザーディレクトリです。すべてのユーザーとグループの管理はプールで行われます。ユーザープールを作成するときは、パスワードポリシーや必要な属性など、ユーザープールのルールを指定する必要があります。

    scripts/ ディレクトリには、create-user-pool.sh というファイルがあります。内容は次のとおりです。

    USER_POOL_ID=$(aws cognito-idp create-user-pool \
      --pool-name recommendation-users \
      --policies '
          {
          "PasswordPolicy": {
            "MinimumLength": 8,
            "RequireUppercase": true,
            "RequireLowercase": true,
            "RequireNumbers": true,
            "RequireSymbols": false
          }
        }' \
      --query 'UserPool.Id' \
      --output text)
    
    echo "User Pool created with id ${USER_POOL_ID}"
    
    echo "export USER_POOL_ID=${USER_POOL_ID}" >> env.sh
    

    このスクリプトは、AWS コマンドラインインターフェイス (AWS CLI) を使用してユーザープールを作成します。ユーザープールに recommendation-users という名前を付けて、パスワードポリシーを指定します。パスワードには、このスクリプトでは 8 文字以上の長さが必要で、さらに大文字、小文字、数字を含める必要があります。

    次のコマンドを使用してスクリプトを実行することにより、ユーザープールを作成できます。

    bash scripts/create-user-pool.sh

    次の出力が表示されます。

    User Pool created with id <user-pool-id>

    次の手順では、ユーザープールにアクセスするクライアントを作成します。

  • ステップ 2.ユーザープールクライアントを作成する

    ユーザープールが設定されたので、ユーザープールクライアントを作成する必要があります。 ユーザープールクライアントは、登録やサインインなど、ユーザープールで認証されていないメソッドを呼び出すために使用します。

    ユーザープールクライアントは、バックエンド Node.js アプリケーションで使用します。登録またはサインインするために、ユーザーは、関連するプロパティを含む HTTP POST リクエストをアプリケーションに作成します。アプリケーションはユーザープールクライアントを使用し、これらのプロパティを Amazon Cognito ユーザープールに転送します。次に、アプリケーションは適切なデータまたはエラーメッセージを返します。

    scripts/ ディレクトリには、ユーザープールクライアントを作成するための create-user-pool-client.sh というファイルがあります。ファイルの内容は次のとおりです。

    source env.sh
    
    CLIENT_ID=$(aws cognito-idp create-user-pool-client \
      --user-pool-id ${USER_POOL_ID} \
      --client-name recommendation-backend \
      --no-generate-secret \
      --explicit-auth-flows ADMIN_NO_SRP_AUTH \
      --query 'UserPoolClient.ClientId' \
      --output text)
    
    echo "User Pool Client created with id ${CLIENT_ID}"
    
    echo "export COGNITO_CLIENT_ID=${CLIENT_ID}" >> env.sh
    

    スクリプトは、新しく作成されたユーザープール用のユーザープールクライアントを作成します。ADMIN_NO_SRP_AUTH フローを使用します。これは、サーバー側アプリケーションで使用できるフローです。サーバー側のフローを実行しているため、モバイルデバイスや単一ページアプリケーションなどのクライアント側のフローで使用するクライアントシークレットは必要ありません。

    次のコマンドを使用して、スクリプトを実行してユーザープールクライアントを作成します。

    bash scripts/create-user-pool-client.sh

    次の出力が表示されます。

    User Pool Client created with id <client-id>

    このモジュールの最後のステップでは、アプリケーションで使用する認証コードについて学習します。

  • ステップ 3.認証コードを確認する

    ユーザープールと、プールにアクセスするクライアントを作成したので、アプリケーションで Amazon Cognito を使用する方法を見てみましょう。

    プロジェクトの application/ ディレクトリに、auth.js というファイルがあります。このファイルには、アプリケーションの認証ヘルパーがいくつか含まれています。そのファイルには 3 つのコア機能があります。それらを順番に確認していきましょう。

    最初の関数は createCognitoUser で、Amazon Cognito で新規ユーザーを登録するときに使用されます。関数は次のようになります。

    const createCognitoUser = async (username, password, email) => {
      const signUpParams = {
        ClientId: process.env.COGNITO_CLIENT_ID,
        Username: username,
        Password: password,
        UserAttributes: [
          {
            Name: 'email',
            Value: email
          }
        ]
      }
      await cognitoidentityserviceprovider.signUp(signUpParams).promise()
      const confirmParams = {
        UserPoolId: process.env.USER_POOL_ID,
        Username: username
      }
      await cognitoidentityserviceprovider.adminConfirmSignUp(confirmParams).promise()
      return {
        username,
        email
      }
    }
    

    前のステップで設定した Amazon Cognito クライアント ID と、ユーザーが指定したユーザー名、パスワード、E メールを使用して、新規ユーザーを作成します。さらに、ユーザーがサインインできるように、ユーザーをすぐに確認します。通常、ユーザーに連絡できるように、ユーザーの E メールや携帯電話番号が正しいかを確かめる確認プロセスを選択します。これはこのチュートリアルの対象外なので、新規ユーザーをただ自動的に確認します。

    2 番目のコアメソッドは、登録済みユーザーが認証を行うときに使用する login 関数です。コードは次のとおりです。

    const login = async (username, password) => {
      const params = {
        ClientId: process.env.COGNITO_CLIENT_ID,
        UserPoolId: process.env.USER_POOL_ID,
        AuthFlow: 'ADMIN_NO_SRP_AUTH',
        AuthParameters: {
          USERNAME: username,
          PASSWORD: password
        }
      }
      const { AuthenticationResult: { IdToken: idToken } }= await cognitoidentityserviceprovider.adminInitiateAuth(params).promise()
      return idToken
    }

    createCognitoUser 関数と同様に、クライアント ID と指定されたパラメータを使用して Amazon Cognito を呼び出します。Amazon Cognito の adminInitiateAuth メソッドは、ユーザーを認証し、認証メソッドが成功した場合にトークンを返します。ユーザーログインに成功したらトークンを返すのは、認証に ID トークンを使用するためです。

    最後に、verifyToken 関数があります。この関数の内容は次のとおりです。

    const verifyToken = async (idToken) => {
      function getKey(header, callback){
        client.getSigningKey(header.kid, function(err, key) {
          var signingKey = key.publicKey || key.rsaPublicKey;
          callback(null, signingKey);
        });
      }
    
      return new Promise((res, rej) => {
        jwt.verify(idToken, getKey, {}, function(err, decoded) {
          if (err) { rej(err) }
          res(decoded)
        })
      })
    }

    この関数は、リクエストで渡された ID トークンを検証します。Amazon Cognito が提供する ID トークンは JSON ウェブトークンで、verifyToken 関数は、トークンが信頼できるソースによって署名されたことを確認し、ユーザーを識別します。この関数は、認証を必要とするエンドポイントで使用され、リクエストを行っているユーザーが確実にアクセスできるようにします。

    後続のモジュールでは、これらの 3 つの認証機能をバックエンドアプリケーションで使用します。


このモジュールでは、Amazon Cognito ユーザープールとユーザープール用のクライアントを作成および設定しました。また、ユーザーの登録、ログイン、検証のために Amazon Cognito ユーザープールとやり取りするユーティリティ関数を見ました。

次のモジュールでは、AWS LambdaAmazon API Gateway などのサーバーレステクノロジーを使用してバックエンドアプリケーションをデプロイします。