Cognito+API Gateway+Lambdaで認証付きAPIを作る
はじめに
Cognito+API Gateway+Lambdaで認証付きAPIを作成しようとしましたが、Cognitoの画面が新しくなったのか想像以上に手こずったため、記事にしました。
前提
以下であることを前提としています。
- AWS CLIがインストール済みであること。
- AWS CLI実行時のIAMユーザのアクセスキーおよびシークレットアクセスキーがcredentialsファイルに記載されていること。
設定の流れ
- Lambdaの設定:APIコール時に動作するLambdaの処理を作成します。本記事では、"Hello from Lambda!"と返すだけのシンプルな処理とします。
- Cognitoの設定:認証基盤として使用するCognitoを設定し、認証対象のユーザを登録します
- API Gatewayの設定:Lambdaとパスを紐づけ、認証基盤にCognitoを使用するよう設定します。
- 動作確認:上記まで完了したら、ターミナルで認証に使用するアクセストークンを取得後、アクセストークンを使って、APIのコールができることを確認します。
Lambdaの設定
Lamndaの管理画面を開き、左ペインの「関数」を選択した後、右ウィンドウの「関数を作成」を押下してください。
以下のキャプチャの通り、設定します。
- 関数名は任意の名称を入力してください。
- ランタイムは、今回はPythonのサンプルアプリケーションを作成するため、Lambdaでサポートされている最新バージョンである3.13を使用します。
- アーキテクチャは今回はどちらでも構いません。
アクセス権限、その他の構成は、今回はデフォルトのままとします。
ここまで設定できたら、右下の「関数の作成」を押下してください。
関数の作成が完了したら、関数の概要のページに遷移します。
画面中央付近のコードタブに以下のデフォルトのソースコードが表示されていればOKです。
import json
def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
Cognitoの設定
ユーザープールの作成
Cognitoを開き、左ペインの「ユーザープール」を選択してください。
右上の「ユーザープールを作成」を押下してください。
以下のキャプチャの通り、設定します。
- 今回は、APIのエンドポイントをcurlで叩くだけとなるので、アプリケーションタイプを「シングルページアプリケーション (SPA)」を選択してください。
- アプリケーションに任意の名称を入力してください
以下のキャプチャの通り、設定します。
- 今回は、メールアドレスを使ったサインインとするため、サインイン識別子のオプションには、「メールアドレス」のチェックボックスにチェックを入れてください。
- 「サインアップのための必須属性」はデフォルトのままとしてください。
- 「リターン URL を追加」はデフォルトのままとしてください。
ユーザプールの概要ページの左ペインの「アプリケーションクライアント」を選択し、先ほど作成したアプリケーションの名称を押下してください。
アプリケーションの概要ページが開くので、「編集」ボタンを押下してください。
「サーバー側の管理者認証情報 (ALLOW_ADMIN_USER_PASSWORD_AUTH) を使用してサインインします」
のチェックボックスにチェックを入れて、画面下部の「変更の保存」を押下してください。
トークン署名キーURLのメモ
アプリケーションクライアントの概要ページに「トークン署名キーURL」という項目があるので、コピーして控えておいてください。
ユーザプールIDのメモ
アプリケーションクライアントの概要ページに「ユーザープール ID」という項目があるので、コピーして控えておいてください。
クライアントIDのメモ
ユーザプールの概要ページに「クライアント ID」という項目があるので、コピーして控えておいてください。
ユーザの作成
動作確認用のユーザを作成します。
左ペインの「ユーザ」を選択し、右ウィンドウの「ユーザを作成」を押下してください。
以下のキャプチャの通り、設定します。
- メールアドレスには、実在する任意のメールアドレスを入力してください。
- パスワードには、任意のパスワードを入力してください
作成ユーザでログイン
アプリケーションクライアントの概要ページにある「ログインページ」タブで、「ログインページを表示」を押下してください。
認証画面が出てくるので、作成ユーザのメールアドレスを入力してください。
続けて、ユーザのパスワードの再設定が求められるので、再設定してください。
入力後、左ペインの「ユーザ」を選択し、右ウィンドウに、ログインしたユーザの「確認ステータス」が「確認済み」となっていればOKです。
API Gatewayの設定
APIの作成
「APIの作成」を押下してください。
今回はシンプルなHTTP APIを使用します。
HTTP APIで、「構築」を押下してください。
任意のAPI名称を入力し、「確認して作成」を押下してください。
ルーティングの設定は後で行います。ここでは、「作成」を押下してください。
ルーティングの設定
左ペインの「Routes」を選択し、右ウィンドウの「作成」を押下してください。
今回は、GETリクエストに対応するエンドポイントを作成するため、プルダウンからGETを選択してください。
パス名は任意のパス名を入力してください(本記事では、/helloとして以降進めます)。
オーソライザーの設定
左ペインの「Authorization」を選択し、右ウィンドウで先ほど作成した、GETのルーティングの設定を選択した状態で、「オーソライザーを作成してアタッチ」を押下してください。
以下のキャプチャの通り、設定し、「作成してアタッチ」を押下してください。
- オーソライザーのタイプには、JWTを選択してください。
- 名前には、任意の名称を入力してください。
- IDソースはデフォルトのままとしてください。
- 発行者 URLには、「トークン署名キーURLのメモ」で控えたURLから "/.well-known/jwks.json"を削除したURLを入力してください
- 対象者には、「クライアントIDのメモ」で控えたクライアントIDを入力してください。
Lambdaプロキシ統合の設定
左ペインの「Integrations」を選択し、右ウィンドウで先ほど作成した、GETのルーティングの設定を選択した状態で、「統合を作成してアタッチ」を押下してください。
以下のキャプチャの通り、設定し、「作成してアタッチ」を押下してください。
- この統合をルートにアタッチするには、先ほど作成した、、GETのルーティングの設定を選択してください。
- 統合タイプには、Lambda関数を選択してください。
- 統合ターゲットのリージョンはデフォルトのままとしてください。
- 統合ターゲットのLambdaは「Lambdaの設定」で作成したLambda関数を選択してください。
- 他の項目はデフォルトのままとしてください。
APIエンドポイントのメモ
左ペインの「API: API名」を選択し、右ウィンドウの「デフォルトのエンドポイント」をコピーし、控えておいてください。
動作確認
アクセストークンの取得
以下を実行すると、"AccessToken"というキーを含むJSONが戻ってくるので、"AccessToken"に対する値をメモしてください。
aws cognito-idp admin-initiate-auth \
--user-pool-id <ユーザプールID> \
--client-id <クライアントID> \
--auth-flow ADMIN_USER_PASSWORD_AUTH \
--auth-parameters "USERNAME=<cognitoに登録したユーザのメールアドレス>,PASSWORD=<cognitoに登録したユーザのパスワード>"
APIのコール
以下を実行し、"Hello from Lambda!"と返ってくれば、成功です。
curl '<APIエンドポイント>' \
-H "Authorization: Bearer <アクセストークン>"
終わりに
ひとまず動作確認が取れるところまで行いました。API GatewayやCognitoの設定についてまだまだ不明な箇所が多々ありますが、少しずつ調べていこうと思います。
Discussion