自定义电子邮件发件人 Lambda 触发器 - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

自定义电子邮件发件人 Lambda 触发器

当您为用户群体分配自定义电子邮件发件人触发器时,如果用户事件要求 Amazon Cognito 发送电子邮件,则它会调用 Lambda 函数,而不是其原定设置行为。使用自定义发件人触发器,您的 Amazon Lambda 函数可以通过您选择的方法和提供商向您的用户发送电子邮件通知。您的函数的自定义代码必须处理和传递用户群体中的所有电子邮件。

注意

目前,您无法在 Amazon Cognito 控制台中分配自定义发件人触发器。您可以在 CreateUserPoolUpdateUserPool API 请求中使用 LambdaConfig 参数分配触发器。

要设置此触发器,请执行以下步骤:

  1. 在 Amazon Key Management Service(Amazon KMS)中创建对称加密密钥 Amazon Cognito 生成密钥(临时密码、验证码和确认码),然后使用此 KMS 密钥对这些密钥进行加密。然后,您可以在 Lambda 函数中使用解密 API 操作来解密这些密钥,并以明文形式将其发送给用户。对于函数中的 Amazon KMS 操作,Amazon Encryption SDK 是一个有用的工具。

  2. 创建一个您要分配为自定义发件人触发器的 Lambda 函数。将您的 KMS 密钥的 kms:Decrypt 权限授予 Lambda 函数角色。

  3. 授予 Amazon Cognito 服务主体 cognito-idp.amazonaws.com 访问权限,以调用 Lambda 函数。

  4. 编写 Lambda 函数代码,将您的消息定向到自定义传递方法或第三方提供商。要传递用户的验证码或确认码,请对请求中 code 参数的值进行 Base64 解码和解密。此操作将生成必须包含在消息中的明文代码或密码。

  5. 更新用户池,使其使用自定义发件人 Lambda 触发器。使用自定义发件人触发器更新或创建用户群体的 IAM 主体必须具有为您的 KMS 密钥创建授予的权限。以下 LambdaConfig 代码段分配自定义短信和电子邮件发件人函数。

    "LambdaConfig": { "KMSKeyID": "arn:aws:kms:us-east-1:123456789012:key/a6c4f8e2-0c45-47db-925f-87854bc9e357", "CustomEmailSender": { "LambdaArn": "arn:aws:lambda:us-east-1:123456789012:function:MyFunction", "LambdaVersion": "V1_0" }, "CustomSMSSender": { "LambdaArn": "arn:aws:lambda:us-east-1:123456789012:function:MyFunction", "LambdaVersion": "V1_0" }

自定义电子邮件发件人 Lambda 触发器参数

Amazon Cognito 传递给此 Lambda 函数的请求是以下参数和 Amazon Cognito 添加到所有请求中的常用参数的组合。

JSON
{ "request": { "type": "customEmailSenderRequestV1", "code": "string", "clientMetadata": { "string": "string", . . . }, "userAttributes": { "string": "string", . . . } }

自定义电子邮件发件人请求参数

type

请求版本。对于自定义电子邮件发件人事件,此字符串的值始终为 customEmailSenderRequestV1

代码

您的函数可以解密并发送给您的用户的加密代码。

clientMetadata

一个或多个键值对,您可以将它们作为自定义输入提供给自定义电子邮件发件人 Lambda 函数触发器。要将此数据传递给 Lambda 函数,您可以在 AdminRespondToAuthChallengeRespondToAuthChallenge API 操作中使用 ClientMetadata 参数。在传递到身份验证后函数的请求中,Amazon Cognito 不包括 AdminInitiateAuthInitiateAuth API 操作的 ClientMetadata 参数中传递的数据。

userAttributes

表示用户属性的一个或多个键值对。

自定义电子邮件发件人响应参数

Amazon Cognito 不需要自定义电子邮件发件人响应中有任何其他返回信息。您的函数可以使用 API 操作来查询和修改资源,或者将事件元数据记录到外部系统。

激活自定义电子邮件发件人 Lambda 触发器

要设置使用自定义逻辑为您的用户池发送电子邮件消息的自定义电子邮件发件人触发器,请按如下方式激活触发器。以下步骤会将自定义电子邮件触发器和/或自定义 SMS 触发器分配给您的用户群体。在您添加自定义电子邮件发件人触发器后,Amazon Cognito 将始终向您的 Lambda 函数发送用户属性(包括电子邮件地址)和一次性代码,而本来会使用 Amazon Simple Email Service 发送电子邮件。

重要

Amazon Cognito HTML 会转义用户临时密码中的保留字符,例如 <&lt;)和 &gt;>)等。这些字符可能出现在 Amazon Cognito 发送到您的自定义电子邮件发件人函数的临时密码中,但不会出现在临时验证码中。要发送临时密码,您的 Lambda 函数在解密密码之后必须取消对这些字符的转义,然后再将消息发送给您的用户。

  1. 在 Amazon KMS 中创建加密密钥。此密钥加密 Amazon Cognito 生成的临时密码和授权代码。然后,您可以在自定义发件人 Lambda 函数中解密这些密钥,将其以明文形式发送给用户。

  2. 授予 Amazon Cognito 服务主体 cognito-idp.amazonaws.com 使用 KMS 密钥加密代码的访问权限。

    将以下基于资源的策略应用于您的 KMS 密钥。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "cognito-idp.amazonaws.com" }, "Action": "kms:CreateGrant", "Resource": "arn:aws:kms:us-west-2:111222333444:key/1example-2222-3333-4444-999example", "Condition": { "StringEquals": { "aws:SourceAccount": "111222333444" }, "ArnLike": { "aws:SourceArn": "arn:aws:cognito-idp:us-west-2:111222333444:userpool/us-east-1_EXAMPLE" } } }] }
  3. 为自定义发件人触发器创建 Lambda 函数。Amazon Cognito 使用 Amazon Encryption SDK 加密密钥、临时密码和授权用户 API 请求的代码。

    1. 为您的 Lambda 函数分配一个 IAM 角色,该角色至少具有对您的 KMS 密钥的 kms:Decrypt 权限。

  4. 授予 Amazon Cognito 服务主体 cognito-idp.amazonaws.com 访问权限,以调用 Lambda 函数。

    以下 Amazon CLI 命令授予 Amazon Cognito 调用 Lambda 函数的权限。

    aws lambda add-permission --function-name lambda_arn --statement-id "CognitoLambdaInvokeAccess" --action lambda:InvokeFunction --principal cognito-idp.amazonaws.com
  5. 编写 Lambda 函数代码以发送消息。Amazon Cognito 使用 Amazon Encryption SDK 加密密钥,然后 Amazon Cognito 会将密钥发送给自定义发件人 Lambda 函数。在您的函数中,解密密钥并处理任何相关的元数据。然后将代码、您自己的自定义消息和目标电话号码发送到传送消息的自定义 API。

  6. 将 Amazon Encryption SDK 添加到 Lambda 函数。有关更多信息,请参阅 Amazon Encryption SDK 编程语言。要更新 Lambda 包,请完成以下步骤:

    1. 在 Amazon Web Services Management Console 中将您的 Lambda 函数作为.zip 文件导出。

    2. 打开您的函数并添加 Amazon Encryption SDK。有关更多信息和下载链接,请参阅 Amazon Encryption SDK Developer Guide(《Crypto SDK 开发人员指南》)中的 Amazon Encryption SDK 编程语言

    3. 压缩您的函数及 SDK 依赖项,然后将函数上传到 Lambda。有关更多信息,请参阅《Amazon Lambda 开发人员指南》中的将 Lambda 函数部署为 .zip 文件归档

  7. 更新用户群体,添加自定义发件人 Lambda 触发器。在 UpdateUserPool API 请求中包含 CustomSMSSenderCustomEmailSender 参数。UpdateUserPool API 操作需要更新用户群体的所有参数 您要更改的参数。如果您没有提供所有相关参数,Amazon Cognito 会将任何缺失参数的值设置为其原定设置。如以下示例所示,包括您想要添加到或保留在用户群体中的所有 Lambda 函数的条目。有关更多信息,请参阅更新用户群体配置

    #Send this parameter in an 'aws cognito-idp update-user-pool' CLI command, including any existing #user pool configurations. --lambda-config "PreSignUp=lambda-arn, \ CustomSMSSender={LambdaVersion=V1_0,LambdaArn=lambda-arn}, \ CustomEmailSender={LambdaVersion=V1_0,LambdaArn=lambda-arn}, \ KMSKeyID=key-id"

要使用 update-user-pool Amazon CLI 删除自定义发件人 Lambda 触发器,请在 --lambda-config 中省略 CustomSMSSenderCustomEmailSender 参数,并包括要与用户群体结合使用的所有其他触发器。

要使用 UpdateUserPool API 请求删除自定义发件人 Lambda 触发器,请在包含其余用户群体配置的请求正文中省略 CustomSMSSenderCustomEmailSender 参数。

代码示例

以下 Node.js 示例在您的自定义电子邮件发件人 Lambda 函数中处理电子邮件事件。此示例假设您的函数定义了两个环境变量。

KEY_ALIAS

要用于加密和解密用户代码的 KMS 密钥的别名

KEY_ARN

要用于加密和解密用户代码的 KMS 密钥的 Amazon 资源名称 (ARN)。

const AWS = require('aws-sdk'); const b64 = require('base64-js'); const encryptionSdk = require('@aws-crypto/client-node'); //Configure the encryption SDK client with the KMS key from the environment variables. const { encrypt, decrypt } = encryptionSdk.buildClient(encryptionSdk.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT); const generatorKeyId = process.env.KEY_ALIAS; const keyIds = [ process.env.KEY_ARN ]; const keyring = new encryptionSdk.KmsKeyringNode({ generatorKeyId, keyIds }) exports.handler = async (event) => { //Decrypt the secret code using encryption SDK. let plainTextCode; if(event.request.code){ const { plaintext, messageHeader } = await decrypt(keyring, b64.toByteArray(event.request.code)); plainTextCode = plaintext } //PlainTextCode now contains the decrypted secret. if(event.triggerSource == 'CustomEmailSender_SignUp'){ //Send an email message to your user via a custom provider. //Include the temporary password in the message. } else if(event.triggerSource == 'CustomEmailSender_ResendCode'){ } else if(event.triggerSource == 'CustomEmailSender_ForgotPassword'){ } else if(event.triggerSource == 'CustomEmailSender_UpdateUserAttribute'){ } else if(event.triggerSource == 'CustomEmailSender_VerifyUserAttribute'){ } else if(event.triggerSource == 'CustomEmailSender_AdminCreateUser'){ } else if(event.triggerSource == 'CustomEmailSender_AccountTakeOverNotification'){ } return; };

自定义电子邮件发件人 Lambda 触发器源

下表显示了 Lambda 代码中自定义电子邮件触发器源的触发事件。

TriggerSource value 事件
CustomEmailSender_SignUp 用户注册,Amazon Cognito 随即发送欢迎消息。
CustomEmailSender_ForgotPassword 用户请求代码以重置其密码。
CustomEmailSender_ResendCode 用户请求更换代码以重置其密码。
CustomEmailSender_UpdateUserAttribute 用户更新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。
CustomEmailSender_VerifyUserAttribute 用户创建新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。
CustomEmailSender_AdminCreateUser 您在用户池中创建新用户,而 Amazon Cognito 向其发送临时密码。
CustomEmailSender_AccountTakeOverNotification Amazon Cognito 检测到接管用户账户的尝试并向用户发送通知。