自訂SMS寄件者 Lambda 觸 - Amazon Cognito

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

自訂SMS寄件者 Lambda 觸

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

此觸發器可提供您可能希望更好地控制使用者集區傳送SMS郵件的方式的案例。您的 Lambda 函數可以自訂對 Amazon SNS API 作業的呼叫,例如當您要管理多個起始IDs或交叉 AWS 區域作業時。您的功能也可能會將郵件重新導向至其他傳遞媒介或第三方服務。

注意

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

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

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

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

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

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

  5. 更新使用者集區,使其使用自訂寄件人 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 新增至所有請求的常用參數之組合。

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 參數的資料,以AdminInitiateAuth及傳遞給後期身份驗證功能的請求中的InitiateAuthAPI操作。

userAttributes

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

自訂SMS寄件者回應參數

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

啟用自訂SMS寄件者 Lambda 觸發器

您可以設定使用自訂邏輯傳送使用者集區的SMS郵SMS件的自訂寄件者觸發器。下列程序會將自訂SMS觸發器、自訂電子郵件觸發器或兩者指派給您的使用者集區。新增自訂SMS寄件者觸發器後,Amazon Cognito 一律會傳送使用者屬性 (包括電話號碼和一次性代碼) 到 Lambda 函數,而不是使用 Amazon 簡單通知服務傳送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. 為您的 Lambda 函數指派IAM角色,該函數至少具有KMS金鑰的kms:Decrypt權限。

  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 使用 AWS Encryption SDK 在 Amazon Cognito 將密碼傳送至自訂寄件者 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 觸發程序。在UpdateUserPoolAPI請求中包含CustomSMSSenderCustomEmailSender參數。此UpdateUserPoolAPI作業需要使用者集區的所有參數以您要變更的參數。如果您未提供所有相關的參數,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,然後包含您要與使用者集區搭配使用的所有其他觸發程序。

若要移除含有UpdateUserPoolAPI要求的自訂寄件者 Lambda 觸發程序,請從包含其餘使用者集區組態的要求主體中省略CustomSMSSenderCustomEmailSender參數。

程式碼範例

下列 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 觸發器 傳送到您的函數中。您的函數可以進行您想要使用此資訊做的事。例如,您可以將程式碼傳送至 Amazon 簡單通知服務 (AmazonSNS) 主題。Amazon SNS 主題訂閱者可以是SMS訊息、HTTPS端點或電子郵件地址。

若要使用自訂SMS寄件者 Lambda 函數建立 Amazon Cognito SMS 簡訊的測試環境,請參閱上的 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 使用者集區中傳送SMS訊息。SMSAmazon Cognito 使用者集區的訊息設定

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