AWS
APIGateway
CognitoUserPools

API GatewayでCognito UserPools Authorizerを使う


UPDATE

下記の内容の元ネタの公式ドキュメントに日本語翻訳作成されたので、そちらを参照してください。


概要

Cognito UserPools AuthorizerをAPI Gatewayに設定してAPIにアクセス制限を設定する方法を説明します。

というか公式ドキュメントの雑な翻訳です

全体としては下記の設定が必要ですが、3以降を記述します。


  1. UserPoolsを作成

  2. API GatewayでAPIを作成する

  3. オーサライザーの設定

  4. リソースに認証を設定

  5. APIへユーザー情報を渡す

アプリのコード例としてjsでのクライアント、API(lambda)側でのスニペットを掲載します


  • クライアント側: 認証とAuthorizationリクエストヘッダの設定

  • API側: lambdaでユーザー情報を受け取る


設定


オーサライザーの設定

任意のAPIの設定画面でオーサライザーを作成する



  1. オーサライザー -> 作成 -> Cognito ユーザープールオーサライザー とクリック


  2. Cognito リージョン, Cognito ユーザープール を選択


  3. オーサライザー名 にわかりやすい名前を入力


  4. IDトークンのソース は「IDトークンをリクエストのどの部分で指定するか」を指定する。特別な理由がなければこのままで(Authorizationヘッダー)


  5. アプリクライントID正規表現 は適宜設定


リソースに認証を設定


  1. リソースのツリーから任意のリソースのメソッドを選択


  2. メソッドリクエスト 内の認証のドロップダウンから作成したオーサライザーを選択


APIへユーザー情報を渡す


  1. リソースのツリーから任意のリソースのメソッドを選択


  2. 統合リクエスト 内の本文マッピングテンプレート で下記の例のようなJSONを設定

{

"email": "$context.authorizer.claims.email",
"sub" : "$context.authorizer.claims.sub"
}

ユーザー属性は $context.authorizer.claims.property 形式で指定する。

属性はUserPoolsで設定したものとデフォルトの属性が使える(?)


コード例(JS)


クライアント側: 認証

amazon-cognito-identity-jsが必要


const IDENTITY_POOL_ID='us-east-1:*****************';
const USER_POOL_ID='us-east-1_*******'
const USER_POOL_APPS_ID='**************************'
AWS.config.region = 'us-east-1'; // Region

AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: IDENTITY_POOL_ID
});

function login(email, password){
const authenticationData = {
Username : email,
Password : password
};
const authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
const userData = {
Username :email,
Pool : userPool
};
const cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
//コールバックは嫌なので結果はPromiseで
return new Promise(function(resolve, reject){
cognitoUser.authenticateUser(authenticationDetails, { onSuccess: resolve, onFailure: reject });
})
}


クライアント側: Authorizationリクエストヘッダの設定


import 'whatwg-fetch'

login('foobar@example.com', 'password').then((auth)=>{
const token = auth.detail.idToken.getJwtToken() //idTokenを使う
const headers = new Header({'Authorization': token}) //IDトークンのソースで設定したヘッダー
return fetch('ENDPOINT', {headers: headers, method: 'GET'})
})


lambdaでユーザー情報を受け取る


function handler(event, context){
/* 本文マッピングテンプレートで指定したキーで参照できる */
console.log(event['email']) // 'foobar@example.com'
}