UPDATE
下記の内容の元ネタの公式ドキュメントに日本語翻訳作成されたので、そちらを参照してください。
概要
Cognito UserPools AuthorizerをAPI Gatewayに設定してAPIにアクセス制限を設定する方法を説明します。
というか公式ドキュメントの雑な翻訳です
全体としては下記の設定が必要ですが、3以降を記述します。
- UserPoolsを作成
- API GatewayでAPIを作成する
- オーサライザーの設定
- リソースに認証を設定
- APIへユーザー情報を渡す
アプリのコード例としてjsでのクライアント、API(lambda)側でのスニペットを掲載します
- クライアント側: 認証と
Authorization
リクエストヘッダの設定 - API側: lambdaでユーザー情報を受け取る
設定
オーサライザーの設定
任意のAPIの設定画面でオーサライザーを作成する
-
オーサライザー
->作成
->Cognito ユーザープールオーサライザー
とクリック -
Cognito リージョン
,Cognito ユーザープール
を選択 -
オーサライザー名
にわかりやすい名前を入力 -
IDトークンのソース
は「IDトークンをリクエストのどの部分で指定するか」を指定する。特別な理由がなければこのままで(Authorization
ヘッダー) -
アプリクライントID正規表現
は適宜設定
リソースに認証を設定
- リソースのツリーから任意のリソースのメソッドを選択
-
メソッドリクエスト
内の認証
のドロップダウンから作成したオーサライザーを選択
APIへユーザー情報を渡す
- リソースのツリーから任意のリソースのメソッドを選択
-
統合リクエスト
内の本文マッピングテンプレート
で下記の例のようなJSONを設定
{
"email": "$context.authorizer.claims.email",
"sub" : "$context.authorizer.claims.sub"
}
ユーザー属性は $context.authorizer.claims.property
形式で指定する。
属性はUserPoolsで設定したものとデフォルトの属性が使える(?)
コード例(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'
}