AWS Builder Center: Learn, Build and Connect with builders in the AWS community
AWS Builder Center is the official home for builders on AWS. Share and read what others are working on, follow people who inspire you, explore training and workshops, and find tools to support what you're building.
如何在 Amazon Cognito 使用者集區中使用自訂電子郵件寄件者 Lambda 觸發機制?
我要調用 Amazon Cognito 自訂電子郵件寄件者 AWS Lambda 觸發機制來處理和傳遞電子郵件訊息。
解決方法
使用 Amazon Cognito 自訂電子郵件寄件者觸發機制,允許第三方供應商從 Lambda 函數程式碼傳送電子郵件通知給您的使用者。Amazon Cognito 會將電子郵件訊息請求傳送至 Lambda 函數。然後,Lambda 函數會處理並傳遞電子郵件訊息。
建立 Lambda 函數,作為您的自訂電子郵件寄件者觸發機制
-
建立名稱為 index.js 的檔案、將下列程式碼新增至檔案,然後儲存變更。
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 has the decrypted secret. if(event.triggerSource == 'CustomEmailSender_SignUp'){ // Send email to end-user using custom or 3rd party provider. // Include temporary password in the email. console.log("CustomEmailSender_SignUp: " + plainTextCode); }else if(event.triggerSource == 'CustomEmailSender_ResendCode'){ console.log("CustomEmailSender_ResendCode: " + plainTextCode); }else if(event.triggerSource == 'CustomEmailSender_ForgotPassword'){ console.log("CustomEmailSender_ForgotPassword: " + plainTextCode); }else if(event.triggerSource == 'CustomEmailSender_UpdateUserAttribute'){ console.log("CustomEmailSender_UpdateUserAttribute: " + plainTextCode); }else if(event.triggerSource == 'CustomEmailSender_VerifyUserAttribute'){ console.log("CustomEmailSender_VerifyUserAttribute: " + plainTextCode); }else if(event.triggerSource == 'CustomEmailSender_AdminCreateUser'){ console.log("CustomEmailSender_AdminCreateUser: " + plainTextCode); }else if(event.triggerSource == 'CustomEmailSender_AccountTakeOverNotification'){ console.log("CustomEmailSender_AccountTakeOverNotification: " + plainTextCode); } return; };**警告:**此程式碼會透過指令碼來解密已加密的保密內容。保密內容是由 Amazon Cognito 傳送的臨時密碼和授權碼。此指令碼也會在日誌中列印純文字程式碼,以供示範之用。但是,以純文字記錄保密內容是一項安全問題。當您的應用程式處於正式作業環境時,請勿在日誌中列印已解密的保密內容。
在 index.js 檔案中新增相關程式碼,以進行從您的自訂電子郵件提供者傳送電子郵件訊息給使用者。 -
建立 .zip 封存檔,亦稱為壓縮的 index.js 檔案:
$ zip function.zip index.js -
開啟 Lambda 主控台。
-
使用 Node.js 執行時期建立 Lambda 函數。
下列是使用 Node.js 14.x 執行時期建立 Lambda 函數的 AWS Command Line Interface (AWS CLI) 命令範例。
**注意:**如果您在執行 AWS CLI 命令時收到錯誤訊息,請確定您使用的是最新版本的 AWS CLI。$ aws lambda create-function --function-name CustomEmailSender --runtime nodejs14.x --handler index.handler --zip-file fileb://function.zip --role ExecutionRoleARN --region REGION**注意:**將 ExecutionRoleARN 取代為您要與 Lambda 函數相關聯的 AWS Identity and Access Management (IAM) 角色 Amazon Resource Name (ARN)。如需詳細資訊,請參閱 Lambda 執行角色。您可以將 CustomEmailSender 取代為您選擇的函數名稱。將 REGION 取代為 AWS 區域代碼。
-
安裝 @aws-crypto/client-node 和 base64-js 模組以使用 AWS Encryption SDK。
如果您沒有安裝 @aws-crypto/client-node 模組,請執行以下動作。請確保在與 Lambda 相容的本機開發環境中執行安裝命令:
建立工作目錄:$ mkdir -p aws-crypto-layer/nodejs變更工作目錄:
$ cd aws-crypto-layer/nodejs使用 npm 軟體封裝管理工具,安裝最新版本的 aws-crypto 模組:
$ npm install @aws-crypto/client-node $ npm install base64-js**注意:**最佳實務是在開發 Lambda 資源時,使用 Amazon Linux 2 環境。當您在 Windows 或 macOS 作業系統進行開發時,請使用 Docker 來安裝 aws-crypto 模組:
$ docker run --entrypoint "" -v "$PWD":/var/task "public.ecr.aws/lambda/nodejs:14" /bin/sh -c "npm install @aws-crypto/client-node; exit"建立要上傳至 Lambda 層的 .zip 檔案:
$ zip -r ../package.zip ../建立包含最新版本 @aws-crypto/client-node 模組的 Lambda 層:
$ aws lambda publish-layer-version --layer-name node_crypto --description "My layer" --license-info "MIT" --compatible-runtimes nodejs14.x --zip-file fileb://../package.zip --region REGION將 Lambda 層添加到您的函數中:
$ aws lambda update-function-configuration --function-name CustomEmailSender --layers arn:aws:lambda:us-east-2:123456789012:layer:node_crypto:1 --region REGION注意:用您的函數名稱替換「CustomEmailSender」。將 arn:aws:lambda:us-east-2:123456789012:layer:node_crypto:1 取代為 publish-layer-version 命令輸出中的 LayerVersionArn 值。將 REGION 取代為 AWS 區域代碼。
在 AWS KMS 中建立加密金鑰
Amazon Cognito 使用 AWS Key Management Service (AWS KMS) 對稱加密金鑰來加密由 Amazon Cognito 產生的臨時密碼和授權碼。
-
使用下列命令來建立 AWS KMS 金鑰:
$ aws kms create-key --description "KMS Key for CustomEmailSender" --region REGION**注意:**將 REGION 取代為區域代碼。
因為此命令未指定金鑰政策,系統會指派預設金鑰政策。若要將自訂金鑰政策套用至您的 AWS KMS 金鑰,請使用 JSON 政策將 --policy 參數新增至命令。請確定您已將 kms:CreateGrant 許可授予執行 UpdateUserPool 操作的 IAM 實體,以便新增自訂電子郵件觸發機制。
當您執行 create-key 命令時,您無法指定別名。若要為新 KMS 金鑰建立別名,請使用 create-alias 命令:$ aws kms create-alias --alias-name alias/custom-email-key --target-key-id KeyId --region REGION**注意:**將 Keyid 取代為 create-key 命令輸出中的金鑰 ID 值。將 REGION 取代為區域代碼。
此程式碼範例依賴環境變數 KEY_ALIAS 和 KEY_ARN 來取得加密金鑰資訊。您必須在 CustomEmailSender 的Lambda 觸發機制中設定這些環境變數。$ aws lambda update-function-configuration --function-name CustomEmailSender --environment 'Variables={KEY_ALIAS=alias/custom-email-key,KEY_ARN=key_ARN}' --region REGION**注意:**將 CustomEmailSender 取代為 Lambda 函數名稱。將 alias/custom-email-key 取代為 AWS KMS 金鑰的金鑰別名。將 key_ARN 取代為 create-key 命令輸出中的 ARN 值。將 REGION 取代為區域代碼。
-
授予 Amazon Cognito 服務主體可調用 Lambda 函數的 cognito-idp.amazonaws.com 許可。使用下列命令將許可授予調用 Lambda 函數的 Amazon Cognito 服務主體。
$ aws lambda add-permission --function-name CustomEmailSender --statement-id "CognitoLambdaInvokeAccess" --action lambda:InvokeFunction --principal cognito-idp.amazonaws.com --source-arn UserPoolArn --region REGION**注意:**將 CustomEmailSender 取代為 Lambda 函數名稱。將 UserPoolArn 取代為使用者集區 ARN。若要尋找使用者集區 ARN,請開啟 Amazon Cognito 主控台使用者集區頁面。然後從清單中選取使用者集區。或者,執行 describe-user-pool 命令。將 REGION 取代為區域代碼。
-
更新 Amazon Cognito 使用者集區,以便它使用自訂電子郵件寄件者 Lambda 觸發機制。設定 UpdateUserPool API 中的 CustomEmailSender 參數。UpdateUserPool 需要使用者集區的所有現有參數以及您要變更的參數。Amazon Cognito 會將任何缺少參數的值設為預設值。如需詳細資訊,請參閱更新使用者集區組態。
在下列範例中,只有 --lambda-config 參數與 CustomEmailSender Lambda 函數詳細資料搭配使用。因此,該命令會將自訂電子郵件寄件者觸發機制新增至您的使用者集區,並將其餘的使用者集區參數設為預設值。如果您使用非預設值設定使用者集區,請傳遞 update-user-pool 命令中的值,避免參數被設為預設值。$ aws cognito-idp update-user-pool --lambda-config "CustomEmailSender={LambdaVersion=V1_0,LambdaArn= LambdaARN},KMSKeyID=KMSKeyARN" --user-pool-id UserPoolId --region REGION**注意:**將 LambdaARN 取代為 create-function 命令輸出中函數的 ARN 值。將 KMSKeyARN 取代為 create-key 命令輸出中提供的 ARN 值。將 UserPoolId 取代為 Amazon Cognito 使用者集區 ID。將 REGION 取代為區域代碼。
測試功能
若要測試 Lambda 函數的整合,請從使用者集區模擬使用者的電子郵件傳送者作業,例如電子郵件驗證或密碼復原。下列範例顯示由 Amazon Cognito 傳送至 Lambda 函數的 ForgotPassword 事件。
{ version: '1', triggerSource: 'CustomEmailSender_ForgotPassword', region: 'us-east-1', userPoolId: 'us-east-1_xxxxxxxx', userName: 'example_user', callerContext: { awsSdkVersion: 'aws-sdk-unknown-unknown', clientId: '12a3b4example-clientid' }, request: { type: 'customEmailSenderRequestV1', code: 'XXXXeBlI7XP3RQmipedVF+7OGa4AgQACABVhdXXXXXXXvLXB1YmxpYy1rZXkAREF6Zk9NR2lBR0FUeDRITStmRHl4RDJyNlpqa2wvWktBbG45ckRmTEpMZ1A3THp4ME9RaVVjVHl3MVFOSEZjS3piZz09AAt1c2VycG9vbC1pZAATdXMtZWFzdC0xX29DOUhnUHVKWgABAAdhd3Mta21zAEthcm46XXdzOmttczp1cy1lYXN0LTE6XXX3XXc0NDA5OXXzOmtleS8yNmQ0ZjVmMy00YmZhLTQ0OXXtODUxZS01ZTM2ZWIwYjhmYjMAuAECAQB42Am0o+Rx0MgG+wLLyKtm1/vTm03JK3jQBZxqABAkreYBMOoAUtm3mLS7+kb2VL0SHgAAAH4wfAYJKoZIhvcNAQcGoG8wbQIBADBoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHjPPHlSWPt+UKrQOQIBEIA7oFUeGe2NPX2cuEVi+Qxwp8/IH1bgyYQut+QbbkElc1rXXXXXbeEVMjMkFQmQufmJyag9v1f+PUalvXwXAAAAAAwAABAAAAAAAAAAAAAAAAAAscZHg8dY/cKTskGQc065mv////8AAAABAAAAAAAAAAAAAAABAAAABpofXaVnP4pmf+yMoCElrOGy7Gn8pIUAZzBlAjEAn/7tuTNko8/HCwXXXXlCOJDeU0SSyB7o9y0TXHM7GptdvmB1JL9OzLxmUg6zChIhAjAFFbH4NrSblvwh/m0inDc11BpeOSKghtg8Pg5Nkf8eY6vmXX6GxjaCuyhBSO7IDcM=', clientMetadata: null, userAttributes: { sub: '1a2b3cde-33cd-402f-5g67-examplesub', 'cognito:user_status': 'CONFIRMED', email_verified: 'true', email: 'user@example.com' } } }
下列範例是純文字程式碼的回應:
CustomEmailSender_ForgotPassword: 12345
您可以在為 Lambda 函數建立的 Amazon CloudWatch 日誌群組中查看完整的日誌。如需如何查看這些日誌的詳細資料,請參閱將 Amazon CloudWatch Logs 與 AWS Lambda 搭配使用。
安裝 @aws-crypto/client-node 和 base64-js 模組以使用 AWS Encryption SDK。
- 語言
- 中文 (繁體)

相關內容
已提問 2 年前
AWS 官方已更新 1 年前