Ao usar o AWS re:Post, você concorda com os AWS re:Post Termos de uso

Como uso o gatilho personalizado do remetente de e-mail do Lambda nos grupos de usuários do Amazon Cognito?

8 minuto de leitura
0

Quero invocar o gatilho do AWS Lambda do remetente de e-mail personalizado do Amazon Cognito para processar e entregar mensagens de e-mail.

Resolução

Use um gatilho de remetente de e-mail personalizado do Amazon Cognito para permitir que provedores terceirizados enviem notificações por e-mail para seus usuários a partir do código de função do Lambda. O Amazon Cognito envia solicitações de mensagens de e-mail para uma função do Lambda. Em seguida, a função do Lambda processa e entrega as mensagens de e-mail.

Criar uma função do Lambda para ser seu gatilho personalizado de remetente de e-mail

  1. Crie um arquivo com o nome index.js, adicione o código a seguir ao arquivo e salve suas alterações.

    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;
    };

    Atenção: Esse código é programado para decifrar segredos criptografados. Os segredos são senhas temporárias e códigos de autorização enviados pelo Amazon Cognito. O script também imprime o código de texto simples em logs para fins de demonstração. No entanto, o registro em log de segredos em texto simples é um problema de segurança. Quando sua aplicação estiver em produção, NUNCA imprima segredos decifrados em logs.
    Adicione o código relevante no arquivo index.js para enviar mensagens de e-mail a usuários do seu provedor de e-mail personalizado.

  2. Crie um arquivamento .zip, também conhecido como arquivo index.js compactado:

    $ zip function.zip index.js
  3. Abra o console do Lambda.

  4. Crie uma função do Lambda com um runtime Node.js.
    Veja a seguir um exemplo de comando da AWS Command Line Interface (AWS CLI) para criar uma função do Lambda com o runtime Node.js 14.x.
    Observação: se receber erros ao executar comandos da AWS CLI, verifique se você está usando a versão mais recente da AWS CLI.

    $ aws lambda create-function --function-name CustomEmailSender --runtime nodejs14.x --handler index.handler --zip-file fileb://function.zip --role ExecutionRoleARN --region REGION

    Observação: substitua ExecutionRoleARN pelo nome do recurso da Amazon (ARN) do perfil do AWS Identity and Access Management (IAM) que você deseja associar à função do Lambda. Para obter mais detalhes, consulte Perfil de execução do Lambda. Você pode substituir CustomEmailSender pelo nome da função de sua escolha. Substitua REGION pelo seu código de região da AWS.

  5. Instale @aws-crypto/client-node e o módulo base64-js para usar o SDK de criptografia da AWS.
    Se você não tem o módulo @aws-crypto/client-node instalado, faça o seguinte. Certifique-se de executar os comandos de instalação em um ambiente de desenvolvimento local compatível com Lambda:
    Crie um diretório de trabalho:

    $ mkdir -p aws-crypto-layer/nodejs

    Altere o diretório de trabalho:

    $ cd aws-crypto-layer/nodejs

    Instale a versão mais recente do módulo aws-crypto com o gerenciador de pacotes npm:

    $ npm install @aws-crypto/client-node
    
    $ npm install base64-js

    Observação: é uma prática recomendada usar um ambiente do Amazon Linux 2 ao desenvolver recursos do Lambda. Use o Docker para instalar o módulo aws-crypto ao desenvolver em um sistema operacional Windows ou macOS:

    $ docker run --entrypoint "" -v "$PWD":/var/task "public.ecr.aws/lambda/nodejs:14" /bin/sh -c "npm install @aws-crypto/client-node; exit"

    Crie um arquivo .zip a ser carregado na sua camada do Lambda:

    $ zip -r ../package.zip ../

    Crie uma camada do Lambda que inclua a versão mais recente do 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

    Adicione a camada do Lambda à sua função:

    $ aws lambda update-function-configuration --function-name CustomEmailSender --layers arn:aws:lambda:us-east-2:123456789012:layer:node_crypto:1 --region REGION

    Observação: Substitua CustomEmailSender pelo nome da sua função. Substitua arn:aws:lambda:us-east-2:123456789012:layer:node_crypto:1 pelo valor LayerVersionArn da saída do comando publish-layer-version. Substitua REGION pelo seu código de região da AWS.

Criar uma chave de criptografia no AWS KMS

O Amazon Cognito usa uma chave de criptografia simétrica do AWS Key Management Service (AWS KMS) para criptografar senhas temporárias e códigos de autorização gerados pelo Amazon Cognito.

  1. Use o seguinte comando para criar uma chave do AWS KMS:

    $ aws kms create-key --description "KMS Key for CustomEmailSender" --region REGION

    Observação: substitua REGION pelo Código da região.
    Como esse comando não especifica uma política de chave, a política de chave padrão é atribuída. Para aplicar uma política de chave personalizada à sua chave do AWS KMS, adicione o parâmetro --policy ao comando com sua política JSON. Certifique-se de conceder a permissão kms:CreateGrant à entidade do IAM que executa a operação UpdateUserPool para adicionar um gatilho de e-mail personalizado.
    Você não pode especificar um alias ao executar o comando create-key. Para criar um alias para a nova chave KMS, use o comando create-alias:

    $ aws kms create-alias --alias-name alias/custom-email-key --target-key-id KeyId --region REGION

    Observação: substitua Keyid pelo valor do ID da chave da saída do comando create-key. Substitua REGION pelo Código da região.
    O exemplo de código se baseia nas variáveis de ambiente KEY_ALIAS e KEY_ARN para informações sobre chaves de criptografia. Você deve configurar essas variáveis de ambiente no gatilho do Lambda CustomEmailSender.

    $ aws lambda update-function-configuration --function-name CustomEmailSender --environment 'Variables={KEY_ALIAS=alias/custom-email-key,KEY_ARN=key_ARN}' --region REGION

    **Observação:**Substitua CustomEmailSender pelo nome da sua função do Lambda. Substitua alias/custom-email-key pelo alias de chave da sua chave do AWS KMS. Substitua key_ARN pelo valor do ARN da saída do comando create-key. Substitua REGION pelo Código da região.

  2. Conceda à entidade principal do serviço Amazon Cognito a permissão cognito-idp.amazonaws.com para invocar a função do Lambda. Use o comando a seguir para conceder permissão à entidade principal de serviço do Amazon Cognito que invoca a função do Lambda.

    $ aws lambda add-permission --function-name CustomEmailSender --statement-id "CognitoLambdaInvokeAccess" --action lambda:InvokeFunction --principal cognito-idp.amazonaws.com --source-arn UserPoolArn --region REGION

    Observação: Substitua CustomEmailSender pelo nome da sua função do Lambda. Substitua UserPoolArn pelo ARN do seu grupo de usuários. Para encontrar o ARN do grupo de usuários, abra a página Grupos de usuários do console do Amazon Cognito. Em seguida, selecione o grupo de usuários na lista. Ou execute o comando describe-user-pool. Substitua REGION pelo Código da região.

  3. Atualize o grupo de usuários do Amazon Cognito para que ele use um gatilho do Lambda de remetente de e-mail personalizado. Defina o parâmetro CustomEmailSender na API UpdateUserPool. UpdateUserPool requer todos os parâmetros existentes do seu grupo de usuários e os parâmetros que você deseja alterar. O Amazon Cognito define os valores de quaisquer parâmetros ausentes de acordo com seus padrões. Para obter mais informações, consulte Updating user pool configuration.
    No exemplo a seguir, somente o parâmetro --lambda-config é usado com os detalhes da função do Lambda CustomEmailSender. Portanto, o comando adiciona o gatilho personalizado do remetente de e-mail ao seu grupo de usuários e define os parâmetros restantes do grupo de usuários como padrão. Se você configurar seu grupo de usuários com valores não padrão, transmita os valores no comando update-user-pool para evitar defini-los como padrão.

    $ aws cognito-idp update-user-pool --lambda-config "CustomEmailSender={LambdaVersion=V1_0,LambdaArn= LambdaARN},KMSKeyID=KMSKeyARN" --user-pool-id UserPoolId --region REGION

    Observação: substitua LambdaARN pelo valor do ARN da função na saída do comando create-function. Substitua KMSKeyARN pelo valor do ARN fornecido na saída do comando create-key. Substitua UserPoolId pelo ID do grupo de usuários do Amazon Cognito. Substitua REGION pelo Código da região.

Testar a funcionalidade

Para testar a integração da função do Lambda, simule uma operação de remetente de e-mail para um usuário do seu grupo de usuários, como verificação de e-mail ou recuperação de senha. O exemplo a seguir mostra um evento ForgotPassword enviado à função do Lambda pelo Amazon Cognito.

{  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'
    }
  }
}

O exemplo a seguir é uma resposta em código de texto simples:

CustomEmailSender_ForgotPassword: 12345

Você pode ver os logs completos no grupo de logs do Amazon CloudWatch criado para sua função do Lambda. Para obter mais detalhes sobre como ver esses logs, consulte Usar logs do Amazon CloudWatch com o AWS Lambda.
Instale @aws-crypto/client-node e o módulo base64-js para usar o SDK de criptografia da AWS.

AWS OFICIAL
AWS OFICIALAtualizada há um ano