本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
自訂 SMS 寄件者 Lambda 觸發程序
若您將自訂簡訊寄件者觸發程序指派至使用者集區,Amazon Cognito 會在使用者事件要求傳送簡訊時,調用 Lambda 函數而非其預設行為。透過自訂寄件者觸發,您的 AWS Lambda 函數可以透過您選擇的方法和提供者傳送簡訊通知給使用者。您函數的自訂程式碼必須從您的使用者集區處理並傳遞所有簡訊。
此觸發程序適用於您可能想要更妥善控制使用者集區傳送簡訊方式的情況。您的 Lambda 函數可以自訂對 Amazon SNS API 操作的呼叫,例如當您想要管理多個起始 IDs 或跨 時 AWS 區域。您的函數也可能將訊息重新導向至另一個交付媒體或第三方服務。
注意
目前,您無法在 Amazon Cognito 主控台中指派自訂寄件者觸發程序。您可以在 CreateUserPool
或 UpdateUserPool
API 請求中透過 LambdaConfig
參數指派觸發程序。
若要設定此觸發程序,請執行下列步驟:
-
在 AWS Key Management Service () 中建立對稱加密金鑰AWS KMS。Amazon Cognito 會產生密碼 (臨時密碼、驗證碼及確認碼),然後使用此 KMS 金鑰將密碼加密。接著您可以在 Lambda 函數中使用 Decrypt API 來解密這些密碼,並以純文字傳送給使用者。AWS Encryption SDK 是您函數中 AWS KMS 操作的實用工具。
-
建立您要指派為自訂寄件者觸發程序的 Lambda 函數。對 Lambda 函數角色授予您 KMS 金鑰的
kms:Decrypt
許可。 -
授予 Amazon Cognito 服務委託人
cognito-idp.amazonaws.com
存取權,以叫用 Lambda 函數。 -
撰寫 Lambda 函數代碼,以將您的訊息引導至自訂傳遞方法或第三方供應商。為了傳遞您的使用者驗證碼或確認碼,Base64 會解碼並解密請求中
code
參數的值。此操作會產生純文字代碼或密碼,且您必須將它加入訊息中。 -
更新使用者集區,使其使用自訂寄件人 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 觸發程序來源
下表說明 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 會將臨時密碼傳送給使用者。 |
自訂 SMS 寄件者 Lambda 觸發程序參數
Amazon Cognito 傳遞至此 Lambda 函數的請求,是以下參數和 Amazon Cognito 新增至所有請求的常用參數之組合。
自訂 SMS 寄件者請求參數
- type
-
請求版本。對於自訂 SMS 寄件者事件,此字串的值一律為
customSMSSenderRequestV1
。 - code
-
您的函數可以解密並傳送給您使用者的加密代碼。
- clientMetadata
-
您可以做為自訂 SMS 寄件者 Lambda 函數觸發程序的自訂輸入提供的一個或多個鍵值組。若要將此資料傳遞至您的 Lambda 函數,您可以使用 AdminRespondToAuthChallenge 和 RespondToAuthChallenge API 動作中的 ClientMetadata 參數。Amazon Cognito 不包含其傳遞至身分驗證後函數的請求中的 AdminInitiateAuth 和 InitiateAuth API 操作的 ClientMetadata 參數中的資料。
- userAttributes
-
代表使用者屬性的一個或多個鍵值組。
自訂 SMS 寄件者回應參數
Amazon Cognito 不預期會在回應中收到任何其他傳回的資訊。您的函數可使用 API 操作來查詢和修改您的資源,或將事件中繼資料記錄到外部系統。
啟用自訂 SMS 寄件者 Lambda 觸發程序
您可以設定自訂 SMS 寄件者觸發程序,以使用自訂邏輯為使用者集區傳送 SMS 訊息。接下來的程序會將自訂 SMS 觸發器、自訂電子郵件觸發器或兩者指派給您的使用者集區。新增自訂 SMS 寄件者觸發程序後,Amazon Cognito 一律會傳送使用者屬性 (包括電話號碼和單次代碼) 到 Lambda 函數,而不是使用 Amazon Simple Notification Service 傳送 SMS 訊息的預設行為。
重要
Amazon Cognito 會在使用者臨時密碼中逸出 HTML 預留字元,例如 <
(<
) 和 >
(>
)。這些字元可能會出現在 Amazon Cognito 傳送至您自訂電子郵件寄件者功能的臨時密碼中,但不會出現在臨時驗證碼中。若要傳送臨時密碼,您的 Lambda 函數必須在解密密碼後以及將訊息傳送給使用者之前取消逸出這些字元。
-
在 AWS KMS中建立加密金鑰。此金鑰可加密 Amazon Cognito 產生的臨時密碼和授權碼。您就可在自訂寄件者 Lambda 函數中解密這些秘密,並以純文字傳送給您的使用者。
-
建立或更新使用者集區的 IAM 主體會針對 Amazon Cognito 用來加密程式碼的 KMS 金鑰建立一次性授權。為您的 KMS 金鑰授予此主體
CreateGrant
許可。若要讓此範例 KMS 金鑰政策有效,更新使用者集區的管理員必須使用 IAM 角色 的擔任角色工作階段登入arn:aws:iam::111222333444:role/my-example-role
。將下列的資源型政策套用至您的 KMS 金鑰。
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "AWS": "
arn:aws:iam::111222333444:role/my-example-role
" }, "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 請求的秘密、臨時密碼和授權碼。
-
將 IAM 角色指派到至少具有 KMS 金鑰
kms:Decrypt
許可的 Lambda 函數。
-
-
授予 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 將秘密傳送至自訂寄件者 Lambda 函數之前,Amazon Cognito 會使用 AWS Encryption SDK 來加密秘密。在您的函數中,解密秘密並處理任何相關的中繼資料。然後將代碼、您自己的自訂訊息和目的地電話號碼傳送到遞送訊息的自訂 API。
-
將 AWS Encryption SDK 新增至 Lambda 函數。如需詳細資訊,請參閱 AWS 加密軟體 SDK 程式設計語言。若要更新 Lambda 套件,請完成下列步驟。
-
將 Lambda 函數在 AWS Management Console匯出為 .zip 檔案。
-
開啟您的 函數並新增 AWS Encryption SDK。如需詳細資訊和下載連結,請參閱 AWS Encryption SDK 開發人員指南中的 AWS Encryption SDK 程式設計語言。
-
使用 SDK 相依性壓縮您的函數,然後將函數上傳至 Lambda。如需詳細資訊,請參閱 AWS Lambda 開發人員指南中的以 .zip 封存檔形式部署 Lambda 函數。
-
-
更新使用者集區以新增自訂寄件者 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. 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
"
若要移除具有 的自訂寄件者 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 Resource Name (ARN)。
部署此函數
-
在您的開發人員工作區中安裝最新版本的 NodeJS。
-
在工作區中建立新的 NodeJS 專案。
-
使用 初始化您的專案
npm init -y
。 -
建立 Lambda 函數的指令碼:
touch index.mjs
。 -
將下列範例的內容貼到
index.mjs
。 -
下載專案相依性: AWS Encryption SDK
npm install @aws-crypto/client-node
。 -
將專案目錄壓縮為檔案:
zip -r my_deployment_package.zip .
。
import { KmsKeyringNode, buildClient, CommitmentPolicy } from '@aws-crypto/client-node'; // Configure the encryption SDK client with the KMS key from the environment variables const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT ); const generatorKeyId = process.env.KEY_ID; const keyIds = [process.env.KEY_ARN]; const keyring = new KmsKeyringNode({ generatorKeyId, keyIds }); // Example function to simulate sending SMS. // This example logs message details to CloudWatch Logs from your Lambda function. // Update this function with custom logic that sends an SMS message to 'phoneNumber' with body 'message'. const sendSMS = async (phoneNumber, message) => { // Log the destination with the phone number masked. console.log(`Simulating SMS send to ${phoneNumber.replace(/[^+]/g, '*')}`); // Log the message with the code masked. console.log(`Message content: ${message.replace(/\b\d{6,8}\b/g, '********')}`); // Simulate API delay await new Promise(resolve => setTimeout(resolve, 100)); console.log('SMS sent successfully'); return true; }; export const handler = async (event) => { try { // Decrypt the secret code using encryption SDK let plainTextCode; if (event.request.code) { const { plaintext, messageHeader } = await decrypt(keyring, Buffer.from(event.request.code, 'base64')); plainTextCode = Buffer.from(plaintext).toString('utf-8'); } // Handle different trigger sources if (event.triggerSource == 'CustomSMSSender_SignUp') { const phoneNumber = event.request.userAttributes.phone_number; const message = `Welcome! Your verification code is: ${plainTextCode}`; await sendSMS(phoneNumber, message); } else if (event.triggerSource == 'CustomSMSSender_ResendCode') { // Handle resend code } else if (event.triggerSource == 'CustomSMSSender_ForgotPassword') { // Handle forgot password } else if (event.triggerSource == 'CustomSMSSender_UpdateUserAttribute') { // Handle update attribute } else if (event.triggerSource == 'CustomSMSSender_VerifyUserAttribute') { // Handle verify attribute } else if (event.triggerSource == 'CustomSMSSender_AdminCreateUser') { // Handle admin create user } return; } catch (error) { console.error('Error in custom SMS sender:', error); throw error; } };
使用自訂 SMS 寄件者函數評估 SMS 訊息功能
自訂 SMS 寄件者 Lambda 函數會接受您的使用者集區將傳送的 SMS 訊息,且該函數會根據您的自訂邏輯傳遞內容。Amazon Cognito 將 自訂 SMS 寄件者 Lambda 觸發程序參數 傳送到您的函數中。您的函數可以進行您想要使用此資訊做的事。例如,您可以將代碼傳送至 Amazon Simple Notification Service (Amazon SNS) 主題。Amazon SNS 主題訂閱者可以是 SMS 訊息、HTTPS 端點或電子郵件地址。
若要使用自訂 SMS 寄件者 Lambda 函數來測試 Amazon Cognito SMS 簡訊的測試環境,請參閱 GitHub 上的 aws-samples 程式庫
當您將此解決方案部署到使用者集區時,對於 Amazon Cognito 通常透過 SMS 簡訊傳送的所有訊息,Lambda 函數會改為傳送到一個中央電子郵件地址。使用此解決方案可以自訂和預覽 SMS 訊息,並測試導致 Amazon Cognito 傳送 SMS 訊息的使用者集區事件。完成測試後,請復原 CloudFormation 堆疊,或從使用者集區中移除自訂 SMS 寄件者函數分配。
重要
請勿使用 amazon-cognito-user-pool-development-and-testing-with-sms-redirected-to-email