¿Cómo uso el desencadenador de Lambda del remitente de correo electrónico personalizado en los grupos de usuarios de Amazon Cognito?
Quiero invocar el desencadenador de AWS Lambda del remitente de correo electrónico personalizado de Amazon Cognito para procesar y entregar los correos electrónicos.
Solución
Use un desencadenador de remitente de correo electrónico personalizado de Amazon Cognito para permitir que terceros envíen notificaciones por correo electrónico a los usuarios desde su código de función de Lambda. Amazon Cognito envía solicitudes de correos electrónicos a una función de Lambda. A continuación, la función de Lambda los procesa y los entrega.
Crear una función de Lambda para que sea su desencadenador de remitente de correo electrónico personalizado
-
Cree un archivo con el nombre index.js, añada el siguiente código al archivo y, a continuación, guarde los cambios.
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; };
Advertencia: Este código cuenta con un script para descifrar secretos cifrados. Los secretos son contraseñas temporales y códigos de autorización que envía Amazon Cognito. El script también imprime el código en texto sin formato en los registros con fines ilustrativos. Sin embargo, registrar secretos en texto sin formato es un problema de seguridad. Cuando la aplicación esté en producción, no imprima NUNCA los secretos descifrados en registros.
Añada el código correspondiente al archivo index.js para enviar correos electrónicos a los usuarios desde su proveedor de correo electrónico personalizado. -
Cree un archivo de archivos.zip, también conocido como archivo index.js comprimido:
$ zip function.zip index.js
-
Abra la consola de Lambda.
-
Cree una función de Lambda con una versión ejecutable de Node.js.
A continuación, se muestra un ejemplo de comando de la Interfaz de la línea de comandos de AWS (AWS CLI) para crear una función de Lambda con la versión ejecutable de Node.js 14.x.
Nota: Si recibe errores al ejecutar los comandos de la AWS CLI, asegúrese de utilizar la versión más reciente.$ aws lambda create-function --function-name CustomEmailSender --runtime nodejs14.x --handler index.handler --zip-file fileb://function.zip --role ExecutionRoleARN --region REGION
Nota: Sustituya ExecutionRoleARN por el nombre de recurso de Amazon (ARN) del rol de AWS Identity and Access Management (IAM) que quiera asociar a la función de Lambda. Para obtener más información, consulte Rol de ejecución de Lambda. Puede sustituir CustomEmailSender por el nombre de la función que prefiera. Sustituya REGIÓN por su región de AWS.
-
Instale el @aws-crypto/client-node y el módulo base64-js para usar el SDK de cifrado de AWS.
Si no tiene instalado el módulo @aws -crypto/client-node, haga lo siguiente. Asegúrese de ejecutar los comandos de instalación en un entorno de desarrollo local que sea compatible con Lambda:
Cree un directorio de trabajo:$ mkdir -p aws-crypto-layer/nodejs
Modifique el directorio de trabajo:
$ cd aws-crypto-layer/nodejs
Instale la versión más reciente del módulo aws-crypto con el administrador de paquetes npm:
$ npm install @aws-crypto/client-node $ npm install base64-js
Nota: Para desarrollar recursos de Lambda, se recomienda usar un entorno de Amazon Linux 2. Utilice Docker para instalar el módulo aws-crypto cuando vaya a desarrollar con un sistema operativo Windows o macOS:
$ docker run --entrypoint "" -v "$PWD":/var/task "public.ecr.aws/lambda/nodejs:14" /bin/sh -c "npm install @aws-crypto/client-node; exit"
Cree un archivo .zip para cargarlo en la capa de Lambda:
$ zip -r ../package.zip ../
Cree una capa de Lambda que incluya la versión más reciente del módulo @aws-crypto/client-node:
$ 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
Añada la capa de Lambda a la función:
$ aws lambda update-function-configuration --function-name CustomEmailSender --layers arn:aws:lambda:us-east-2:123456789012:layer:node_crypto:1 --region REGION
Nota: Sustituya CustomEmailSender por el nombre de su función. Sustituya arn:aws:lambda:us-east- 2:123456789012:layer:node\ _crypto:1 por el valor LayerVersionArn de la salida del comando publish-layer-version. Sustituya REGIÓN por su región de AWS.
Crear una clave de cifrado en AWS KMS
Amazon Cognito utiliza una clave de cifrado simétrica de AWS Key Management Service (AWS KMS) para cifrar las contraseñas temporales y los códigos de autorización que genera Amazon Cognito.
-
Utilice el siguiente comando para crear una clave de AWS KMS:
$ aws kms create-key --description "KMS Key for CustomEmailSender" --region REGION
Nota: Sustituya REGIÓN por el código de su región.
Como este comando no especifica una política de claves, se asigna la política de claves predeterminada. Para aplicar una política de claves personalizada a su clave de AWS KMS, añada el parámetro**--policy** al comando con la política de JSON. Asegúrese de conceder el permiso kms:CreateGrant a la entidad de IAM que realiza la operación UpdateUserPool para añadir un desencadenador de correo electrónico personalizado.
No puede especificar un alias al ejecutar el comando create-key. Si quiere crear un alias para la nueva clave de KMS, utilice el comando create-alias:$ aws kms create-alias --alias-name alias/custom-email-key --target-key-id KeyId --region REGION
Nota: Sustituya Keyid por el valor del ID de clave de la salida del comando create-key. Sustituya REGIÓN por el código de su región.
El ejemplo de código se basa en las variables de entorno KEY_ALIAS y KEY_ARN para obtener información sobre la clave de cifrado. Debe configurar estas variables de entorno en el desencadenador de Lambda CustomEmailSender.$ aws lambda update-function-configuration --function-name CustomEmailSender --environment 'Variables={KEY_ALIAS=alias/custom-email-key,KEY_ARN=key_ARN}' --region REGION
Nota: Sustituya CustomEmailSender por el nombre de su función de Lambda. Sustituya alias/custom-email-key por el alias de clave de su clave de AWS KMS. Sustituya key_ARN por el valor del ARN de la salida del comando create-key. Sustituya REGIÓN por el código de su región.
-
Otorgue a la entidad principal del servicio Amazon Cognito el permiso cognito-idp.amazonaws.com para invocar la función de Lambda. Utilice el siguiente comando para conceder el permiso a la entidad principal del servicio Amazon Cognito que invoca la función de Lambda.
$ aws lambda add-permission --function-name CustomEmailSender --statement-id "CognitoLambdaInvokeAccess" --action lambda:InvokeFunction --principal cognito-idp.amazonaws.com --source-arn UserPoolArn --region REGION
Nota: Sustituya CustomEmailSender por el nombre de su función de Lambda. Sustituya UserPoolArn por el ARN de su grupo de usuarios. Para encontrar el ARN del grupo de usuarios, abra la página Grupos de usuarios de la consola de Amazon Cognito. A continuación, en la lista, seleccione el grupo de usuarios o ejecute el comando describe-user-pool. Sustituya REGIÓN por el código de su región.
-
Actualice el grupo de usuarios de Amazon Cognito para que utilice un desencadenador Lambda de remitente de correo electrónico personalizado. Establezca el parámetro CustomEmailSender en la API UpdateUserPool. UpdateUserPool necesita todos los parámetros existentes de su grupo de usuarios y los parámetros que quiera cambiar. Amazon Cognito establece como predeterminados los valores de los parámetros que faltan. Para obtener más información, consulte Updating user pool configuration.
En el siguiente ejemplo, solo se usa el parámetro --lambda-config con los detalles de la función de Lambda CustomEmailSender. Por lo tanto, el comando añade el desencadenador del remitente de correo electrónico personalizado a su grupo de usuarios y establece como predeterminados los parámetros restantes. Si configura su grupo de usuarios con valores no predeterminados, pase los valores en el comando update-user-pool para evitar configurarlos como predeterminados.$ aws cognito-idp update-user-pool --lambda-config "CustomEmailSender={LambdaVersion=V1_0,LambdaArn= LambdaARN},KMSKeyID=KMSKeyARN" --user-pool-id UserPoolId --region REGION
Nota: Sustituya LambdaARN por el valor del ARN de la función de la salida del comando create-function. Sustituya KMSKeyARN por el valor del ARN proporcionado en la salida del comando create-key. Sustituya UserPoolId por su ID del grupo de usuarios de Amazon Cognito. Sustituya REGIÓN por el código de su región.
Probar si funciona
Para probar la integración de la función de Lambda, simule una operación de remitente de correo electrónico para un usuario de su grupo de usuarios, como la verificación del correo electrónico o la recuperación de la contraseña. En el siguiente ejemplo, se muestra cómo Amazon Cognito envía un evento ForgotPassword a la función de Lambda.
{ 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' } } }
En el siguiente ejemplo, se muestra una respuesta con código en texto sin formato:
CustomEmailSender_ForgotPassword: 12345
Puede ver los registros completos en el grupo de registros de Amazon CloudWatch que se ha creado para la función de Lambda. Para obtener más información sobre cómo verlos, consulte Uso de Registros de Amazon CloudWatch con AWS Lambda.
Instale el @aws-crypto/client-node y el módulo base64-js para usar el SDK de cifrado de AWS.
Contenido relevante
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace 2 años
- OFICIAL DE AWSActualizada hace 2 años
- OFICIAL DE AWSActualizada hace 6 meses