¿Cómo uso el desencadenador de Lambda del remitente de correo electrónico personalizado en los grupos de usuarios de Amazon Cognito?

9 minutos de lectura
0

Tengo que 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

1.    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.

2.    Cree un archivo de archivos.zip, también conocido como archivo index.js comprimido:

$ zip function.zip index.js

3.    Abra la consola de Lambda.

4.    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 <specify a 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 <specify a region> por su código de región de AWS.

5.    Instale el @aws-crypto/client-node para usar el SDK de cifrado de AWS.

Si no tiene instalado el módulo @aws-crypto/client-node, debe completar las siguientes tareas de alto nivel:

  • Instale el módulo.
  • Cree un paquete con la versión más reciente del módulo.
  • Cree una capa de Lambda que contenga la dependencia que puede usar con la función de Lambda.

Nota: Ejecute 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

Nota: Para desarrollar recursos de Lambda, se recomienda usar un entorno de Amazon Linux 2. Utilice Docker para instalar el módulo aws-crypto al 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 subirlo a 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 <specify a 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 <specify a 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 <specify a region> por su código de región.

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.

1.    Cree una clave de AWS KMS:

$ aws kms create-key --description "KMS Key for CustomEmailSender" --region <specify a region>

Nota: Sustituya <specify a region> por su código de 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 <specify a region>

Nota: Sustituya <KeyId> por el valor del ID de clave de la salida del comando create-key. Sustituya <specify a region> por su código de 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 <specify a 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 <specify a region> por su código de región.

Conceda el permiso cognito-idp.amazonaws.com a la entidad principal del servicio Amazon Cognito para invocar la función de Lambda

Use el siguiente comando para conceder permiso a la entidad principal del servicio Amazon Cognito para invocar 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 <specify a 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 <specify a region> por su código de región.

Actualizar el grupo de usuarios de Amazon Cognito para que utilice un desencadenador de Lambda de remitente de correo electrónico personalizado

Modifique el grupo de usuarios configurando 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 Actualización de la configuración del grupo de usuarios.

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 <specify a 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 de grupo de usuarios de Amazon Cognito. Sustituya <specify a region> por su código de 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 Acceso a los registros de Amazon CloudWatch para AWS Lambda.

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace un año