Cognito idTokenをAPI GW&Lambdaで受け取ってデコードする手順についてのメモ書きです。
やりたいこと
- Cognitoでログインし、idToken(jwt)を払い出す。
- 手順1のidTokenを利用し、APIGWで作成された認証必要なAPIを呼び出す。
- Cognito Authorizerでユーザー認証を行い、バックエンドのLambdaを起動する。
- Lambdaで手順1のidTokenを受け取り、デコードする(emailなどのユーザー情報を取得する)。
Cognito Userpool
-
Userpoolの作成手順は割愛します。
-
idTokenの払い出しについて、SDKなどを使うことも可能ですが、今回はホストされたUIを使います。(コールバックURLはいったんlocalhostとします)
Lambda
レイヤー
レイヤーを作っておきます。今回は「python-jose」というpythonのライブラリを使います。
python-joseをダウンロードし、zip化します。
$ pip3 install python-jose -t python
$ zip -r9 layer.zip python
Lambda関数
下記のLambda関数を作成します。
- ランタイム: Python 3.11
- アーキテクチャ: x86_64
- 基本的な Lambda アクセス権限で新しいロールを作成
- レイヤー: 上記手順で作成したレイヤー
- ソースコード(eventのheadersからidTokenを取り出し、デコードしユーザーのemailを取得):
import json from jose import jwt def lambda_handler(event, context): token = event["headers"]["Authorization"] decoded_token = jwt.get_unverified_claims(token) email = decoded_token["email"] return { "statusCode": 200, "body": json.dumps(f"Hello, {email}!") }
APIGW
オーソライザー
下記のオーソライザーを作成します。
- オーソライザーのタイプ: Cognito
- Cognito ユーザープール: 上記手順で作成したCognitoユーザープールを選択
- トークンのソース: Authorization
API
下記のAPIを作成します。
- APIタイプ: REST API
- リソース: /
- メソッド: GET
- 統合タイプ: Lambda 関数(上記手順で作成したLambdaを選択)
- メソッドリクエスト:
- 認可: 上記手順で作成したCognitoオーソライザーを選択
- 統合リクエスト:
- マッピングテンプレート:
- コンテンツタイプ: application/json
#set($inputRoot = $input.path('$')) { "headers": { "Authorization": "$input.params().header.get('Authorization')" } }
- マッピングテンプレート:
動作確認
$ curl -H "Authorization: <ログイン時に払い出したidToken>" -X GET <APIエンドポイント>
レスポンス
{"statusCode": 200, "body": "\"Hello, test-user@sample.com!\""}