自訂 SMS 寄件者 Lambda 觸發程序 - Amazon Cognito

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

自訂 SMS 寄件者 Lambda 觸發程序

若您將自訂簡訊寄件者觸發程序指派至使用者集區,Amazon Cognito 會在使用者事件要求傳送簡訊時,調用 Lambda 函數而非其預設行為。使用自定義發件人觸發器,您的 AWS Lambda 功能可以通過您選擇的方法和提供商向用戶發送 SMS 通知。您函數的自訂程式碼必須從您的使用者集區處理並傳遞所有簡訊。

注意

目前,您無法在 Amazon Cognito 主控台中指派自訂寄件者觸發程序。您可以在 CreateUserPoolUpdateUserPool API 請求中透過 LambdaConfig 參數指派觸發程序。

若要設定此觸發程序,請執行下列步驟:

  1. 在 AWS Key Management Service (AWS KMS) 中建立對稱加密金鑰。Amazon Cognito 會產生密碼 (臨時密碼、驗證碼及確認碼),然後使用此 KMS 金鑰將密碼加密。接著您可以在 Lambda 函數中使用 Decrypt API 來解密這些密碼,並以純文字傳送給使用者。對於函數中的 AWS KMS 操作而言,AWS Encryption SDK這是一個有用的工具。

  2. 建立您要指派為自訂寄件者觸發程序的 Lambda 函數。對 Lambda 函數角色授予您 KMS 金鑰的 kms:Decrypt 許可。

  3. 授予 Amazon Cognito 服務委託人 cognito-idp.amazonaws.com 存取權,以叫用 Lambda 函數。

  4. 撰寫 Lambda 函數代碼,以將您的訊息引導至自訂傳遞方法或第三方供應商。為了傳遞您的使用者驗證碼或確認碼,Base64 會解碼並解密請求中 code 參數的值。此操作會產生純文字代碼或密碼,且您必須將它加入訊息中。

  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" }

自訂 SMS 寄件者 Lambda 觸發程序參數

Amazon Cognito 傳遞至此 Lambda 函數的請求,是以下參數和 Amazon Cognito 新增至所有請求的常用參數之組合。

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

自訂 SMS 寄件者請求參數

type

請求版本。對於自訂 SMS 寄件者事件,此字串的值一律為 customSMSSenderRequestV1

code

您的函數可以解密並傳送給您使用者的加密代碼。

clientMetadata

您可以做為自訂 SMS 寄件者 Lambda 函數觸發程序的自訂輸入提供的一個或多個鍵值組。若要將此資料傳遞至 Lambda 函數,您可以在AdminRespondToAuthChallengeRespondToAuthChallengeAPI 動作中使用 ClientMetadata 參數。Amazon Cognito 不會在傳遞給身份驗證後功能的請求中包含來自 ClientMetadata 參數AdminInitiateAuthInitiateAuthAPI 操作的資料。

userAttributes

代表使用者屬性的一個或多個鍵值組。

自訂 SMS 寄件者回應參數

Amazon Cognito 不預期會在回應中收到任何其他傳回的資訊。您的函數可使用 API 操作來查詢和修改您的資源,或將事件中繼資料記錄到外部系統。

啟用自訂 SMS 寄件者 Lambda 觸發程序

您可以設定自訂 SMS 寄件者觸發程序,以使用自訂邏輯為使用者集區傳送 SMS 訊息。接下來的程序會將自訂 SMS 觸發器、自訂電子郵件觸發器或兩者指派給您的使用者集區。新增自訂 SMS 寄件者觸發程序後,Amazon Cognito 一律會傳送使用者屬性 (包括電話號碼和單次代碼) 到 Lambda 函數,而不是使用 Amazon Simple Notification Service 傳送 SMS 訊息的預設行為。

重要

Amazon Cognito 會在使用者臨時密碼中逸出 HTML 預留字元,例如 &lt; (<) 和 &gt; (>)。這些字元可能會出現在 Amazon Cognito 傳送至您自訂電子郵件寄件者功能的臨時密碼中,但不會出現在臨時驗證碼中。若要傳送臨時密碼,您的 Lambda 函數必須在解密密碼後以及將訊息傳送給使用者之前取消逸出這些字元。

  1. 在 AWS 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 使用 AWS 加密 SDK 來加密授權使用者 API 請求的秘密、臨時密碼和授權碼。

    1. 將 IAM 角色指派到至少具有 KMS 金鑰 kms:Decrypt 許可的 Lambda 函數。

  4. 授予 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
  5. 撰寫 Lambda 函數程式碼以傳送訊息。Amazon Cognito 會在 Amazon Cogni AWS Encryption SDK to 將密碼傳送至自訂寄件者 Lambda 函數之前,用來加密機密。在您的函數中,解密秘密並處理任何相關的中繼資料。然後將代碼、您自己的自訂訊息和目的地電話號碼傳送到遞送訊息的自訂 API。

  6. 新增 AWS Encryption SDK 至您的 Lambda 函數。如需詳細資訊,請參閱 AWS 加密軟體 SDK 程式設計語言。若要更新 Lambda 套件,請完成下列步驟。

    1. 將 Lambda 函數在 AWS Management Console匯出為 .zip 檔案。

    2. 打開您的功能並添加 AWS Encryption SDK. 如需詳細資訊和下載連結,請參閱 AWS Encryption SDK 開發人員指南中的 AWS Encryption SDK 程式設計語言

    3. 使用 SDK 相依性壓縮您的函數,然後將函數上傳至 Lambda。如需詳細資訊,請參閱 AWS Lambda 開發人員指南中的以 .zip 封存檔形式部署 Lambda 函數

  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"

若要使用移除自訂寄件者 Lambda 觸發程序 update-user-pool AWS CLI,請省略CustomSMSSenderCustomEmailSender參數--lambda-config,然後包含您要與使用者集區搭配使用的所有其他觸發程序。

若要使用 UpdateUserPool API 請求移除自訂寄件者 Lambda 觸發條件,請從包含其他使用者集區組態的請求內文省略 CustomSMSSenderCustomEmailSender 參數。

程式碼範例

下列 Node.js 範例處理您的自訂 SMS 寄件者 Lambda 函數中的 SMS 訊息事件。此範例假設您的函數定義了兩個環境變數。

KEY_ALIAS

您想要用來加密和解密使用者程式碼的 KMS 金鑰的別名

KEY_ARN

您想要用來加密和解密使用者程式碼的 KMS 金鑰的 Amazon Resource Name (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 觸發程序參數 傳送到您的函數中。您的函數可以進行您想要使用此資訊做的事。例如,您可以將代碼傳送至 Amazon Simple Notification Service (Amazon SNS) 主題。Amazon SNS 主題訂閱者可以是 SMS 訊息、HTTPS 端點或電子郵件地址。

若要使用自訂簡訊傳送者 Lambda 函數建立 Amazon Cognito 簡訊的測試環境,請參閱上的 AWS 範例程式庫sms-redirected-to-email中的 amazon-cognito-user-pooldevelopment-and-testing-with-。 GitHub存放庫包含可 AWS CloudFormation 建立新使用者集區或使用您已有的使用者集區的範本。這些範本會建立 Lambda 函數和 Amazon SNS 主題。由範本指派為自訂 SMS 寄件者觸發程序的 Lambda 函數,會將您的 SMS 訊息重新導向至 Amazon SNS 主題的訂閱者。

當您將此解決方案部署到使用者集區時,對於 Amazon Cognito 通常透過 SMS 簡訊傳送的所有訊息,Lambda 函數會改為傳送到一個中央電子郵件地址。使用此解決方案可以自訂和預覽 SMS 訊息,並測試導致 Amazon Cognito 傳送 SMS 訊息的使用者集區事件。完成測試後,回滾 CloudFormation 堆棧,或從用戶池中刪除自定義 SMS 發送者功能分配。

重要

不要使用 amazon-cognito-user-pool-development-and-testing-with- 中的模板sms-redirected-to-email來構建生產環境。解決方案中的自訂 SMS 寄件者 Lambda 函數會模擬 SMS 訊息,但 Lambda 函數會將它們全部傳送到一個中央電子郵件地址。您必須先完成在 Amazon Cognito 使用者集區的簡訊設定 顯示的需求,才能在實際產品的 Amazon Cognito 使用者集區中傳送 SMS 訊息。

自訂簡訊寄件者 Lambda 觸發程序來源

下表說明 Lambda 程式碼中自訂簡訊觸發程序來源的觸發事件。

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 會將臨時密碼傳送給使用者。