💡

Cognito+API Gateway+Lambdaで認証付きAPIを作る

に公開

はじめに

Cognito+API Gateway+Lambdaで認証付きAPIを作成しようとしましたが、Cognitoの画面が新しくなったのか想像以上に手こずったため、記事にしました。

前提

以下であることを前提としています。

  • AWS CLIがインストール済みであること。
  • AWS CLI実行時のIAMユーザのアクセスキーおよびシークレットアクセスキーがcredentialsファイルに記載されていること。

設定の流れ

  1. Lambdaの設定:APIコール時に動作するLambdaの処理を作成します。本記事では、"Hello from Lambda!"と返すだけのシンプルな処理とします。
  2. Cognitoの設定:認証基盤として使用するCognitoを設定し、認証対象のユーザを登録します
  3. API Gatewayの設定:Lambdaとパスを紐づけ、認証基盤にCognitoを使用するよう設定します。
  4. 動作確認:上記まで完了したら、ターミナルで認証に使用するアクセストークンを取得後、アクセストークンを使って、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