

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

# 自定义发件人 Lambda 触发器
<a name="user-pool-lambda-custom-sender-triggers"></a>

Lambda 触发器 `CustomEmailSender` 和 `CustomSMSSender` 支持在用户池中使用第三方电子邮件和短信通知。您可以选择 SMS 和电子邮件提供商，通过 Lambda 函数代码向用户发送通知。当 Amazon Cognito 向用户发送邀请、MFA 代码、确认码、验证码或临时密码时，这些事件会激活您配置的 Lambda 函数。Amazon Cognito 将代码和临时密码（密钥）发送到您激活的 Lambda 函数。Amazon Cognito 使用 AWS KMS 客户管理的密钥对这些机密进行加密，然后. AWS Encryption SDK AWS Encryption SDK 是一个客户端加密库，可帮助您加密和解密通用数据。

**[CustomEmailSender](user-pool-lambda-custom-email-sender.md)**  
Amazon Cognito 调用此触发器向用户发送电子邮件通知。

**[自定义SMSSender](user-pool-lambda-custom-sms-sender.md)**  
Amazon Cognito 调用此触发器向用户发送 SMS 通知。

## 加密概念
<a name="user-pool-lambda-custom-sender-triggers-resources"></a>

Amazon Cognito 不会在发送给自定义发件人触发器的事件中以明文形式发送用户的代码。Lambda 函数必须解密事件中的代码。以下概念是加密架构，您的函数必须使用该架构来获取可以传递给用户的代码。

**AWS KMS**  
AWS KMS 是一项用于创建和控制 AWS KMS 密钥的托管服务。这些密钥加密您的数据。有关更多信息，请参阅[什么是 AWS Key Management Service？](/kms/latest/developerguide/overview.html)。

**KMS 密钥**  
KMS 密钥是加密密钥的逻辑表示形式。KMS 密钥包含元数据，如密钥 ID、创建日期、描述和密钥状态。KMS 密钥还包含用于加密和解密数据的密钥材料。有关更多信息，请参阅 [AWS KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms_keys)。

**对称 KMS 密钥**  
对称 KMS 密钥是一个 256 位加密密钥，它不会退出 AWS KMS 而不加密。要使用对称 KMS 密钥，必须调用 AWS KMS。Amazon Cognito 使用对称密钥。加密和解密使用同一密钥。有关更多信息，请参阅[对称 KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#symmetric-cmks)。

## 有关自定义发件人 Lambda 触发器的需知信息
<a name="user-pool-lambda-custom-sender-triggers-things-to-know"></a>
+ 要配置用户池以使用这些 Lambda 触发器，您可以使用 AWS CLI 或开发工具包。无法从 Amazon Cognito 控制台进行这些配置。

  `UpdateUserPool` 操作可设置 Lambda 配置。对此操作的请求需要包含用户池的所有参数*和* 您要更改的参数。如果您没有提供所有相关参数，Amazon Cognito 会将任何缺失参数的值设置为其原定设置。如下面的 AWS CLI 示例所示，包括您要添加到用户池或保留在用户池中的所有 Lambda 函数的条目。有关更多信息，请参阅 [更新用户池和应用程序客户端配置](cognito-user-pool-updating.md)。

  ```
      #Send this parameter in an 'aws cognito-idp update-user-pool' CLI command, including any existing 
      #user pool configurations. This snippet also includes a pre sign-up trigger for syntax reference. The pre sign-up trigger
      #doesn't have a role in custom sender triggers.
                
        --lambda-config "PreSignUp=lambda-arn, \
                         CustomSMSSender={LambdaVersion=V1_0,LambdaArn=lambda-arn}, \
                         CustomEmailSender={LambdaVersion=V1_0,LambdaArn=lambda-arn}, \
                         KMSKeyID=key-id"
  ```

  对于使用 `UpdateUserPool` 的 JSON 正文的请求，以下 `LambdaConfig` 代码段可分配自定义的短信和电子邮件发件人函数。

  ```
  "LambdaConfig": {
     "KMSKeyID": "arn:aws:kms:us-east-1:111122223333:key/a6c4f8e2-0c45-47db-925f-87854bc9e357",
     "CustomEmailSender": {
        "LambdaArn": "arn:aws:lambda:us-east-1:111122223333:function:MyFunction",
        "LambdaVersion": "V1_0"
     },
     "CustomSMSSender": {
        "LambdaArn": "arn:aws:lambda:us-east-1:111122223333:function:MyFunction",
        "LambdaVersion": "V1_0"
     }
  ```
+ 要使用`update-user-pool` AWS CLI 命令移除自定义发送器 Lambda 触发器，请省略`CustomSMSSender`或`CustomEmailSender`参数`--lambda-config`，并包含您要在用户池中使用的所有其他触发器。

  要使用 `UpdateUserPool` API 请求删除自定义发件人 Lambda 触发器，请在包含其余用户池配置的请求正文中省略 `CustomSMSSender` 或 `CustomEmailSender` 参数。
+ Amazon Cognito HTML 会转义用户临时密码中的保留字符，例如 `<`（`&lt;`）和 `&gt;`（`>`）等。这些字符可能出现在 Amazon Cognito 发送到您的自定义电子邮件发件人函数的临时密码中，但不会出现在临时验证码中。要发送临时密码，您的 Lambda 函数在解密密码之后必须取消对这些字符的转义，然后再将消息发送给您的用户。

## 激活自定义发件人 Lambda 触发器
<a name="enable-custom-sender-lambda-trigger"></a>

要使用自定义逻辑为您的用户池发送短信或电子邮件消息，请设置自定义发件人触发器。以下步骤会将自定义短信触发器和/或自定义电子邮件触发器分配给您的用户池。添加自定义发件人触发器后，Amazon Cognito 始终向您的 Lambda 函数发送用户属性（包括电话号码）和一次性代码，而不是采用发送短信或电子邮件消息的默认行为。

1. 在 AWS Key Management Service (AWS KMS) 中创建[对称加密密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#symmetric-cmks)。Amazon Cognito 生成密钥（临时密码、验证码、身份验证一次性密码和确认码），然后使用此 KMS 密钥通过 [AWS Encryption SDK](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html) 对这些密钥进行加密。然后，您可以 AWS Encryption SDK 在 Lambda 函数中使用解密密密钥并将其以明文形式发送给用户。

1. 创建或更新您的用户池的 IAM 主体会针对 Amazon Cognito 用于加密代码的 KMS 密钥创建一次性授权。请为该主体授予对您的 KMS 密钥的 `CreateGrant` 权限。要使本示例中的 KMS 密钥策略生效，更新用户池的管理员必须以 IAM 角色 `arn:aws:iam::111222333444:role/my-example-administrator-role` 的代入角色会话身份登录。

   请将以下基于资源的策略（已针对您的环境进行修改）应用于您的 KMS 密钥。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
       {
           "Effect": "Allow",
           "Principal": {
               "AWS": "arn:aws:iam::111122223333:role/my-example-administrator-role"
           },
           "Action": "kms:CreateGrant",
           "Resource": "arn:aws:kms:us-west-2:111122223333:key/1example-2222-3333-4444-999example",
           "Condition": {
               "StringEquals": {
                  "kms:EncryptionContext:userpool-id": "us-west-2_EXAMPLE"
               }
           }
       },
       {
           "Sid": "Allow Lambda to decrypt",
           "Effect": "Allow",
           "Principal": {
               "AWS": "arn:aws:iam::111122223333:role/my-lambda-function-role"
           },
           "Action": "kms:Decrypt",
           "Resource": "*"
       }]
   }
   ```

------

1. 为自定义发件人触发器创建 Lambda 函数。Amazon Cognito 使用 [AWS Encryption SDK ](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html)加密密钥、临时密码和授权用户 API 请求的代码。

   1. 分配一个 [Lambda 执行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)，该角色至少具有针对您的 KMS 密钥的 `kms:Decrypt` 权限。

   1. 编写 Lambda 函数代码以发送消息。您函数的输入事件将包含一个密钥。在您的函数中，使用解密密密钥 AWS Encryption SDK 并处理所有相关的元数据。然后将代码、您自己的自定义消息和目标电话号码发送到传送消息的自定义 API。

   1. 将 AWS Encryption SDK 添加到您的 Lambda 函数中。有关更多信息，请参阅 [AWS Encryption SDK 编程语言](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/programming-languages.html)。要更新 Lambda 包，请完成以下步骤：

      1. 在 AWS 管理控制台中将您的 Lambda 函数作为.zip 文件导出。

      1. 打开您的函数并添加 AWS Encryption SDK. 有关更多信息和下载链接，请参阅 *AWS Encryption SDK Developer Guide*（《Crypto SDK 开发人员指南》）中的 [AWS Encryption SDK 编程语言](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/programming-languages.html)。

      1. 压缩您的函数及 SDK 依赖项，然后将函数上传到 Lambda。有关更多信息，请参阅《AWS Lambda 开发人员指南》**中的[将 Lambda 函数部署为 .zip 文件归档](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-zip.html#configuration-function-create)。

1. 授予 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
   ```

1. 使用添加自定义发送器 Lambda 触发器的`LambdaConfig`参数生成 [UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)API 请求。此类触发器无法通过 Amazon Cognito 控制台添加。自定义发件人触发器要求 `LambdaConfig` 参数中必须包含 `KMSKeyID` 以及 `CustomSMSSender` 或 `CustomEmailSender`（或两者同时包含）。