自定义电子邮件发件人 Lambda 触发器
当您为用户群体分配自定义电子邮件发件人触发器时,如果用户事件要求 Amazon Cognito 发送电子邮件,则它会调用 Lambda 函数,而不是其原定设置行为。使用自定义发件人触发器,您的 AWS Lambda 函数可以通过您选择的方法和提供商向您的用户发送电子邮件通知。您的函数的自定义代码必须处理和传递用户群体中的所有电子邮件。
此触发器适用于以下场景:您可能希望更好地控制用户池发送电子邮件消息的方式。您的 Lambda 函数可以自定义对 Amazon SES API 操作的调用,例如,当您想要管理多个经过验证的身份或跨 AWS 区域时。您的函数还可能将消息重定向到另一个传递媒介或第三方服务。
注意
目前,您无法在 Amazon Cognito 控制台中分配自定义发件人触发器。您可以在 CreateUserPool
或 UpdateUserPool
API 请求中使用 LambdaConfig
参数分配触发器。
要设置此触发器,请执行以下步骤:
-
在 AWS Key Management Service(AWS KMS)中创建对称加密密钥 Amazon Cognito 生成密钥(临时密码、验证码和确认码),然后使用此 KMS 密钥对这些密钥进行加密。然后,您可以在 Lambda 函数中使用解密 API 操作来解密这些密钥,并以明文形式将其发送给用户。对于函数中的 AWS KMS 操作,AWS Encryption SDK 是一个有用的工具。
-
创建一个您要分配为自定义发件人触发器的 Lambda 函数。将您的 KMS 密钥的
kms:Decrypt
权限授予 Lambda 函数角色。 -
授予 Amazon Cognito 服务主体
cognito-idp.amazonaws.com
访问权限,以调用 Lambda 函数。 -
编写 Lambda 函数代码,将您的消息定向到自定义传递方法或第三方提供商。要传递用户的验证码或确认码,请对请求中
code
参数的值进行 Base64 解码和解密。此操作将生成必须包含在消息中的明文代码或密码。 -
更新用户池,使其使用自定义发件人 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 添加到所有请求中的常用参数的组合。
自定义电子邮件发件人请求参数
- type
-
请求版本。对于自定义电子邮件发件人事件,此字符串的值始终为
customEmailSenderRequestV1
。 - 代码
-
您的函数可以解密并发送给您的用户的加密代码。
- clientMetadata
-
一个或多个键值对,您可以将它们作为自定义输入提供给自定义电子邮件发件人 Lambda 函数触发器。要将此数据传递给 Lambda 函数,您可以在 AdminRespondToAuthChallenge 和 RespondToAuthChallenge API 操作中使用 ClientMetadata 参数。在传递到身份验证后函数的请求中,Amazon Cognito 不包括 AdminInitiateAuth 和 InitiateAuth API 操作的 ClientMetadata 参数中传递的数据。
注意
在具有以下触发源的事件中,Amazon Cognito 会向自定义电子邮件触发函数发送
ClientMetadata
:-
CustomEmailSender_ForgotPassword
-
CustomEmailSender_SignUp
-
CustomEmailSender_Authentication
Amazon Cognito 不会在具有源
CustomEmailSender_AccountTakeOverNotification
的触发事件中发送ClientMetadata
。 -
- userAttributes
-
表示用户属性的一个或多个键值对。
自定义电子邮件发件人响应参数
Amazon Cognito 不需要自定义电子邮件发件人响应中有任何其他返回信息。您的 Lambda 函数必须解释事件并解密代码,然后传送消息内容。典型的函数会组装电子邮件消息并将其定向到第三方 SMTP 中继。
激活自定义电子邮件发件人 Lambda 触发器
要设置使用自定义逻辑为您的用户池发送电子邮件消息的自定义电子邮件发件人触发器,请按如下方式激活触发器。以下步骤会将自定义电子邮件触发器和/或自定义 SMS 触发器分配给您的用户群体。在您添加自定义电子邮件发件人触发器后,Amazon Cognito 将始终向您的 Lambda 函数发送用户属性(包括电子邮件地址)和一次性代码,而本来会使用 Amazon Simple Email Service 发送电子邮件。
重要
Amazon Cognito HTML 会转义用户临时密码中的保留字符,例如 <
(<
)和 >
(>
)等。这些字符可能出现在 Amazon Cognito 发送到您的自定义电子邮件发件人函数的临时密码中,但不会出现在临时验证码中。要发送临时密码,您的 Lambda 函数在解密密码之后必须取消对这些字符的转义,然后再将消息发送给您的用户。
-
在 AWS KMS 中创建加密密钥。此密钥加密 Amazon Cognito 生成的临时密码和授权代码。然后,您可以在自定义发件人 Lambda 函数中解密这些密钥,将其以明文形式发送给用户。
-
授予 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
" } } }] } -
为自定义发件人触发器创建 Lambda 函数。Amazon Cognito 使用 AWS Encryption SDK 加密密钥、临时密码和授权用户 API 请求的代码。
-
为您的 Lambda 函数分配一个 IAM 角色,该角色至少具有对您的 KMS 密钥的
kms:Decrypt
权限。
-
-
授予 Amazon Cognito 服务主体
cognito-idp.amazonaws.com
访问权限,以调用 Lambda 函数。以下 AWS CLI 命令授予 Amazon Cognito 调用 Lambda 函数的权限。
aws lambda add-permission --function-name
lambda_arn
--statement-id "CognitoLambdaInvokeAccess
" --action lambda:InvokeFunction --principal cognito-idp.amazonaws.com -
编写 Lambda 函数代码以发送消息。Amazon Cognito 使用 AWS Encryption SDK 加密密钥,然后 Amazon Cognito 会将密钥发送给自定义发件人 Lambda 函数。在您的函数中,解密密钥并处理任何相关的元数据。然后将代码、您自己的自定义消息和目标电话号码发送到传送消息的自定义 API。
-
将 AWS Encryption SDK 添加到 Lambda 函数。有关更多信息,请参阅 AWS Encryption SDK 编程语言。要更新 Lambda 包,请完成以下步骤:
-
在 AWS Management Console 中将您的 Lambda 函数作为.zip 文件导出。
-
打开您的函数并添加 AWS Encryption SDK。有关更多信息和下载链接,请参阅 AWS Encryption SDK Developer Guide(《Crypto SDK 开发人员指南》)中的 AWS Encryption SDK 编程语言。
-
压缩您的函数及 SDK 依赖项,然后将函数上传到 Lambda。有关更多信息,请参阅《AWS Lambda 开发人员指南》中的将 Lambda 函数部署为 .zip 文件归档。
-
-
更新用户群体,添加自定义发件人 Lambda 触发器。在
UpdateUserPool
API 请求中包含CustomSMSSender
或CustomEmailSender
参数。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
AWS CLI 删除自定义发件人 Lambda 触发器,请在 --lambda-config
中省略 CustomSMSSender
或 CustomEmailSender
参数,并包括要与用户群体结合使用的所有其他触发器。
要使用 UpdateUserPool
API 请求删除自定义发件人 Lambda 触发器,请在包含其余用户群体配置的请求正文中省略 CustomSMSSender
或 CustomEmailSender
参数。
代码示例
以下 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_Authentication'){ //Send an MFA message. } else if(event.triggerSource == 'CustomEmailSender_ResendCode'){ //Send a message with next steps for password reset. } else if(event.triggerSource == 'CustomEmailSender_ForgotPassword'){ //Send a message with next steps for password reset. } else if(event.triggerSource == 'CustomEmailSender_UpdateUserAttribute'){ //Send a message with next steps for confirming the new attribute. } else if(event.triggerSource == 'CustomEmailSender_VerifyUserAttribute'){ //Send a message with next steps for confirming the new attribute. } else if(event.triggerSource == 'CustomEmailSender_AdminCreateUser'){ //Send a message with next steps for signing in with a new user profile. } else if(event.triggerSource == 'CustomEmailSender_AccountTakeOverNotification'){ //Send a message describing the threat protection event and next steps. } return; };
自定义电子邮件发件人 Lambda 触发器源
下表显示了 Lambda 代码中自定义电子邮件触发器源的触发事件。
TriggerSource value |
事件 |
---|---|
CustomEmailSender_SignUp |
用户注册,Amazon Cognito 随即发送欢迎消息。 |
CustomEmailSender_Authentication |
用户会登录,且 Amazon Cognito 会发送多重身份验证(MFA)代码。 |
CustomEmailSender_ForgotPassword |
用户请求代码以重置其密码。 |
CustomEmailSender_ResendCode |
用户请求替换账号确认代码。 |
CustomEmailSender_UpdateUserAttribute |
用户更新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。 |
CustomEmailSender_VerifyUserAttribute |
用户创建新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。 |
CustomEmailSender_AdminCreateUser |
您在用户池中创建新用户,而 Amazon Cognito 向其发送临时密码。 |
CustomEmailSender_AccountTakeOverNotification |
Amazon Cognito 检测到接管用户账户的尝试并向用户发送通知。 |