🛠️

API GatewayからStep FunctionsステートマシンにCognitoユーザの情報を渡したい!

2023/06/04に公開

この記事で得られること

  • API GatewayからStep FunctionsにCognitoユーザの認証情報を引き渡す方法
  • API Gatewayの統合リクエストを使って任意のinputをStep Functionsに渡す方法

はじめに

Step Functionsのステートマシン中で、API Gatewayを叩いたCognitoユーザの情報をLambda関数を経由して、DynamoDBに保存したいという要件がありました。
その実装に手間取ってしまいましたので、備忘録がてら記事としてその方法を共有したいと思います。

API GatewayでCognitoユーザの認証情報を取得する

API Gatewayでは、Cognitoユーザプールを使ってアクセス制御ができるCognitoユーザプールオーソライザーを提供しています。
(参照: https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html)

Cognitoユーザプールオーソライザーは、Cognitoユーザプールから取得したIDトークンもしくはアクセストークンを使用して、APIの呼び出しに関する認可機能を提供します。
この機能のフローは下図の通りとなります。

Cognitoオーソライザーのフローチャート

Cognitoユーザプールオーソライザーでのトークンの検証後、トークンが正しいものであればユーザ情報を取得することができます。
IDトークンを使用した場合のユーザ情報のペイロードは、以下URLをご参照ください。
(参照: https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-id-token.html)

API Gatewayから統合リクエストを使用してAWSサービスを実行する場合、このペイロードが requestContext.authorizer.claims の下に配置されています。
したがって、サービスを呼び出す側からこのペイロードを参照すれば良いことになります。

Step Functionsでユーザ情報を参照する方法

API GatewayのLambda統合を使用する場合、リクエストを受信するとリクエストヘッダーやパラメータ、ペイロードなどを含む event オブジェクトをLambda関数に引き渡します。
(参考: https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html )

しかし、AWSサービス統合ではLambda統合と違って event オブジェクトが用意されていないので、何らかの方法でStep Functionsステートマシンに入力を持たせる必要があります。
そこで、統合リクエスト中のマッピングテンプレート機能を使用します。

マッピングテンプレート機能はリクエストヘッダーやパラメータ、ペイロードなどを加工して、AWSサービスへの入力として用いるものです。
今回はこれを使用することにより、Step Functionsステートマシンにユーザ情報を入力します。
なお、マッピングテンプレートの詳細につきましては、以下をご参照ください。
(参照: https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html)

Step Functionsのステートマシンでは、 input 文字列で入力を渡すことが可能です。
また、この文字列はJSON文字列である必要があるので、一部記号をエスケープする必要があります。

先ほど説明した通り、Cognitoユーザプールオーソライザーから取得したユーザ情報のペイロードは requestContext.authorizer.claims の下に配置されています。
これをマッピングテンプレート中から呼び出すには、 $context 変数を使用します。
Step Functionsステートマシンにユーザ名を executedUser として渡すには、以下のマッピングテンプレートを設定します。

{
  "input": "{\"executedUser\":\"$context.authorizer.claims['cognito:username']\"}"
}

これにより、Step Functionステートマシンにユーザ名を渡すことができました。

おわりに

以上がAPI GatewayからStep FunctionsにCognitoユーザの認証情報を渡す方法になります。
当初 input をJSON文字列にしなければならない部分を失念しており、うまく動作しない状況が続いていました。
API GatewayとStep Functionsとの統合にお困りの方の一助となりましたら幸いです。

AWS CDK v2を使うとStep Functionsにヘッダーやペイロードをよしなにして渡してくれるらしいですね。
今後開発でCDKを使える機会があれば、そちらも使ってみたいと思います。
(参考: https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-step-functions-rest-api-integration-cdk.html)

この度は本記事を読んでいただきましてありがとうございました。

Discussion