AWS CognitoでサインアップしたユーザをLambdaでDynamoDBに登録する
概要
AWS Cognito でサインアップ(登録)したユーザを、DB(DynamoDB)に登録したいというケースは割と存在するかと思います。
※前提として、Cognito はユーザマスタとしては使用すべきではなく、DB は別に持つことが推奨されています。
そこで、今回は、AWS Cognito でサインアップしたユーザを Lambda で DynamoDB に登録する為の最小構成を作ってみます。
実現方法としては、画面側で CognitoSDK を呼び出した後に DynamoDB に Insert しに行くなどの方法も考えられるかと思いますが、画面側処理に依存するのは望ましくないため、バックエンド側で、Cognito のトリガー機能を用いて、E-mail などの認証が完了したタイミングで、Lambda を呼び出し、ユーザ情報を DB(DynamoDB)に連携します。
構成
今回実施するのは以下のような最小構成とします。
実際には、Cognito の E-mail 認証前の登録画面や、認証後の追加会員情報登録画面などを作り、必要な会員情報を登録させるようにすると良いでしょう。
- Cognito で保持するデータ
- ユーザ名(id):cognito が払い出した UUID
- ログイン ID(E-mail):ユーザ登録時に入力した e-mail(有効性確認済)
- パスワード:ユーザ登録時に入力したパスワード
- DynamoDB で保持するデータ
- id : cognito が払い出した UUID。パーティションキー
- E-mail:ユーザ属性情報としての E-mail アドレス
前提
- Cognito ユーザプールは構成済みであること
- DynamoDB にユーザテーブルを作成済みであること
- Lambda ランタイム:今回は Node.js を使用します
なお、Cognito ユーザプールを SAM で作成している場合は、呼び出す Lambda トリガ、Lambda もまとめて SAM で設定できると思いますが、今回は、個別に Cognito が作成済み(個別に紐づけ設定が必要)の前提とします。
また、この Lambda トリガーは会員登録時以外に、パスワード忘れからの確認にもコールされると思いますので、既に会員登録済の場合の考慮は別途行う必要があります。
構築方法
lambda 関数の準備
次のような内容の Lambda 関数を作成します。
行っている処理の内容としてはシンプルで、event
で cognito 側からユーザの E-mail 確認が完了したタイミングで、対象ユーザの情報を受け取り、DynamoDB のUser
という名前のテーブルに対して、Cognito のユーザ名(UUID)をキーにして、属性情報と共にputItem
行っています。
const dynamodb = require("aws-sdk/clients/dynamodb");
const docClient = new dynamodb.DocumentClient();
exports.signupLinkToDBHandler = async (event, context, callback) => {
var params = {
TableName: "User",
Item: {
id: event.userName,
email: event.request.userAttributes.email,
},
};
const result = await docClient.put(params).promise();
console.log(
`cognito user link to dynamodb id=${event.userName} email=${event.request.userAttributes.email} result=${result}`
);
callback(null, event);
};
DynamoDB へのアクセス権の付与
この処理を実行するためには、lambda 関数が DynamoDB にアクセスできる必要があります。対象の Lambda の実行ロール(IAM ロール)に対して、DynamoDB の対象テーブルに対して Put する権限を付与します。
DynamoDB の各種操作権限一式を与える場合はAmazonDynamoDBFullAccess
になります。(必要に応じて細かい権限を設定してください)
SAM テンプレートの定義例を記載しておきます。(SAM で構築する場合、AWS コンソールから登録する場合は、権限を個別に設定してください)
ポイントとしては、Policies
に対してAmazonDynamoDBFullAccess
を設定しているところくらいになります。
AWSTemplateFormatVersion: 2010-09-09
Description: >-
cognito-trigger-sample
Transform:
- AWS::Serverless-2016-10-31
Resources:
signupLinkToDBFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/signup-link-lambda.signupLinkToDBHandler
Runtime: nodejs14.x
Architectures:
- x86_64
MemorySize: 128
Timeout: 100
Description: Link cognito users to DB.
Policies:
- AWSLambdaBasicExecutionRole
- AmazonDynamoDBFullAccess
Cognito のトリガ設定
Cognito 側から、E-mail 確認時に Lambda 関数を呼び出すように以下のように設定します。
- AWS コンソールから、
Cognito
-ユーザプール
で対象のユーザプールを選択します。 -
全般設定
-トリガー
を選択します。 -
確認後
の項目で対象の Lambda 関数を選択し、変更の保存
を押下して設定を反映します。
以上の設定で、Cognito でユーザ登録して E-mail 確認を行うと、DynamoDB に対して、ユーザ情報が Put されるようになります。
※正常に動作しない場合は、CloudWatchLogs にログが出力されていると思いますので、確認してみてください。
Discussion