本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
自定义SMS发件人 Lambda 触发器
当您为用户池分配自定义发SMS件人触发器时,当用户事件要求其发送消息时,Amazon Cognito 会调用 Lambda 函数,而不是其默认行为。SMS使用自定义发件人触发器,您的 AWS Lambda 函数可以通过您选择的方法和提供商向用户发送SMS通知。您的函数的自定义代码必须处理和传送用户池中的所有SMS消息。
此触发器适用于您可能希望更好地控制用户池发送SMS消息的方式。您的 Lambda 函数可以自定义对 Amazon SNS API 操作的调用,例如,当您想要管理多个起源或IDs交叉时。 AWS 区域您的函数还可能将消息重定向到其他传送媒体或第三方服务。
注意
目前,您无法在 Amazon Cognito 控制台中分配自定义发件人触发器。您可以在CreateUserPool
或UpdateUserPool
API请求中为触发器分配带LambdaConfig
参数的触发器。
要设置此触发器,请执行以下步骤:
-
在 AWS Key Management Service (AWS KMS) 中创建对称加密密钥。Amazon Cognito 会生成密钥(临时密码、验证码和确认码),然后使用此密钥对机密进行加密。KMS然后,您可以在 Lambda 函数中使用解密API操作来解密密密钥并将其以明文形式发送给用户。AWS Encryption SDK是对函数进行 AWS KMS 操作的有用工具。
-
创建一个您要分配为自定义发件人触发器的 Lambda 函数。向 Lambda 函数
kms:Decrypt
角色授予KMS密钥权限。 -
授予 Amazon Cognito 服务主体
cognito-idp.amazonaws.com
访问权限,以调用 Lambda 函数。 -
编写 Lambda 函数代码,将您的消息定向到自定义传递方法或第三方提供商。要传递用户的验证码或确认码,请对请求中
code
参数的值进行 Base64 解码和解密。此操作将生成必须包含在消息中的明文代码或密码。 -
更新用户池,使其使用自定义发件人 Lambda 触发器。使用自定义发送者触发器更新或创建用户池的IAM委托人必须有权为您的KMS密钥创建授权。以下
LambdaConfig
代码段分配了自定义函数SMS和电子邮件发件人函数。"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" }
自定义SMS发件人 Lambda 触发器参数
Amazon Cognito 传递给此 Lambda 函数的请求是以下参数和 Amazon Cognito 添加到所有请求中的常用参数的组合。
自定义SMS发件人请求参数
- type
-
请求版本。对于自定义SMS发送者事件,此字符串的值始终为
customSMSSenderRequestV1
。 - 代码
-
您的函数可以解密并发送给您的用户的加密代码。
- clientMetadata
-
您可以将一个或多个键值对作为自定义输入提供给自定义发送者 SMS Lambda 函数触发器。要将此数据传递给您的 Lambda 函数,您可以使用AdminRespondToAuthChallenge和 ClientMetadata RespondToAuthChallengeAPI操作中的参数。Amazon Cognito 在传递给身份验证后函数的请求中不包含来自 ClientMetadata 参数AdminInitiateAuth和InitiateAuthAPI操作的数据。
- userAttributes
-
表示用户属性的一个或多个键值对。
自定义SMS发件人响应参数
Amazon Cognito 不需要响应中任何额外的返回信息。您的函数可以使用API操作来查询和修改您的资源,或者将事件元数据记录到外部系统。
激活自定义SMS发送器 Lambda 触发器
您可以设置自定义发SMS件人触发器,该触发器使用自定义逻辑向您的用户池发送SMS消息。以下过程将自定义SMS触发器、自定义电子邮件触发器或两者分配给您的用户池。添加自定义发SMS件人触发器后,Amazon Cognito 始终将用户属性(包括电话号码和一次性代码)发送到您的 Lambda 函数,而不是SMS使用亚马逊简单通知服务发送消息的默认行为。
重要
Amazon HTML Cognito 会对用户临时密码中的 <
(<
) 和 >
(>
) 等保留字符进行转义。这些字符可能出现在 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 加密SDK来加密授权用户API请求的机密、临时密码和代码。
-
为您的 Lambda 函数分配一个至少具有密钥
kms:Decrypt
KMS权限的IAM角色。
-
-
授予 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 给自定义发件人 Lambda 函数之前,Amazon Cognito 使用它来加密机密。在您的函数中,解密密钥并处理任何相关的元数据。然后将验证码、您自己的自定义消息和目标电话号码发送给发送API消息的自定义机构。
-
将 AWS Encryption SDK 添加到您的 Lambda 函数中。有关更多信息,请参阅AWS 加密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
"
要删除带有的自定义发件人 Lambda 触发器 update-user-pool
AWS CLI,请省略CustomSMSSender
或CustomEmailSender
参数--lambda-config
,并包含您要与用户池一起使用的所有其他触发器。
要删除带有UpdateUserPool
API请求的自定义发送者 Lambda 触发器,请省略包含用户池其余配置的请求正文中的CustomSMSSender
或CustomEmailSender
参数。
代码示例
以下 Node.js 示例在您的自定义SMS发送器 Lambda 函数中处理SMS消息事件。此示例假设您的函数定义了两个环境变量。
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 == 'CustomSMSSender_SignUp'){ //Send an SMS message to your user via a custom provider. //Include the temporary password in the message. } else if(event.triggerSource == 'CustomSMSSender_ResendCode'){ } else if(event.triggerSource == 'CustomSMSSender_ForgotPassword'){ } else if(event.triggerSource == 'CustomSMSSender_UpdateUserAttribute'){ } else if(event.triggerSource == 'CustomSMSSender_VerifyUserAttribute'){ } else if(event.triggerSource == 'CustomSMSSender_AdminCreateUser'){ } else if(event.triggerSource == 'CustomSMSSender_AccountTakeOverNotification'){ } return; };
使用自定义SMS发件人函数评估SMS消息功能
自定义SMS发送者 Lambda 函数接受您的用户池将要发送的SMS消息,该函数根据您的自定义逻辑传递内容。Amazon Cognito 将 自定义SMS发件人 Lambda 触发器参数 发送到您的函数。您的函数可以用这些信息做您想做的事。例如,您可以将代码发送到亚马逊简单通知服务 (AmazonSNS) 主题。Amazon SNS 主题订阅者可以是SMS消息、HTTPS终端节点或电子邮件地址。
要使用自定义发件人 SMS Lambda 函数为 Amazon Cognito SMS 消息传递创建测试环境,请参阅上的 aws-samp amazon-cognito-user-poolles development-and-testing-with 库sms-redirected-to-email中的--
当您将此解决方案部署到用户池时,Amazon Cognito 通常通过SMS消息发送的所有消息,Lambda 函数会改为发送到中央电子邮件地址。使用此解决方案自定义和预览SMS消息,并测试导致 Amazon Cognito 发送SMS消息的用户池事件。完成测试后,回滚 CloudFormation 堆栈,或者从用户池中移除自定义SMS发送器函数分配。
重要
不要使用 amazon-cognito-user-pool-development-and-testing-with-
自定义SMS发件人 Lambda 触发源
下表显示了 Lambda 代码中自定义SMS触发源的触发事件。
TriggerSource value |
事件 |
---|---|
CustomSMSSender_SignUp |
用户注册,Amazon Cognito 随即发送欢迎消息。 |
CustomSMSSender_ForgotPassword |
用户请求代码以重置其密码。 |
CustomSMSSender_ResendCode |
用户请求新代码以确认其注册。 |
CustomSMSSender_VerifyUserAttribute |
用户创建新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。 |
CustomSMSSender_UpdateUserAttribute |
用户更新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。 |
CustomSMSSender_Authentication |
配置了SMS多重身份验证 (MFA) 的用户登录。 |
CustomSMSSender_AdminCreateUser |
您在用户池中创建新用户,而 Amazon Cognito 向其发送临时密码。 |