Amazon Cognito 사용자 풀에서 사용자 지정 이메일 발신자 Lambda 트리거를 사용하려면 어떻게 해야 하나요?

6분 분량
0

Amazon Cognito 사용자 지정 이메일 발신자 AWS Lambda 트리거를 간접적으로 호출해 이메일 메시지를 처리하고 전송하고 싶습니다.

해결 방법

Amazon Cognito 사용자 지정 이메일 발신자 트리거를 사용하면 타사 공급자가 Lambda 함수 코드를 통해 사용자에게 이메일 알림을 보낼 수 있습니다. Amazon Cognito는 Lambda 함수에 이메일 메시지 요청을 보냅니다. 그런 다음 Lambda 함수는 이메일 메시지를 처리하고 전달합니다.

사용자 지정 이메일 발신자 트리거로 사용할 Lambda 함수를 생성하십시오.

  1. 이름이 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 파일에 추가합니다.

  2. .zip 파일 아카이브(압축된 index.js 파일이라고도 함)를 생성합니다.

    $ zip function.zip index.js
  3. Lambda 콘솔을 엽니다.

  4. Node.js 런타임으로 Lambda 함수를 생성합니다.
    다음은 Node.js 14.x 런타임으로 Lambda 함수를 생성하기 위한 AWS 명령줄 인터페이스(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 리소스 이름(ARN)으로 변경합니다. 자세한 내용은 Lambda 실행 역할을 참고하세요. 사용자 지정 이메일 발신자를 선택한 함수 이름으로 바꿀 수 있습니다. 리전을 AWS 리전으로 바꾸세요.

  5. @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 -암호화/클라이언트-노드 모듈을 포함하는 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

    참고:****사용자 지정 이메일 발신자를 함수 이름으로 바꾸십시오. arn:aws:lambda:us-east-2:123456789012:layer:node_crypto:1publish-layer-version 명령 출력의 LayerVersionArn 값으로 바꾸세요. 리전을 AWS 리전으로 바꾸세요.

AWS KMS에서 암호화 키 생성

Amazon Cognito에서는 AWS Key Management Service(AWS KMS)의 대칭 암호화 키를 사용해 Amazon Cognito에서 생성한 임시 암호 및 권한 부여 코드를 암호화합니다.

  1. 다음 명령을 사용해 AWS KMS 키를 생성하세요.

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

    참고:****리전을 사용자의 리전으로 바꾸세요.
    이 명령에서는 키 정책을 지정하지 않기 때문에 기본 키 정책이 할당됩니다. AWS KMS 키에 사용자 지정 키 정책을 적용하려면 JSON 정책과 함께 명령에**\ --policy** 파라미터를 추가하세요. UpdateUserPool 작업을 실행하는 IAM 엔티티에 KMS:CreateGrant 권한을 부여하여 사용자 지정 이메일 트리거를 추가해야 합니다.
    create-key 명령을 실행할 때는 별칭을 지정할 수 없습니다. 새 KMS 키의 별칭을 만들려면 create-alias 명령을 사용하십시오.

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

    참고: Keyidcreate-key 명령 출력의 키 ID 값으로 바꾸세요. 리전을 사용자의 리전으로 바꾸세요.
    코드 예시의 경우 암호화 키 정보용 환경 변수 KEY_ALIASKEY_ARN을 사용합니다. 사용자 지정 이메일 발신자 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_ARNcreate-key 명령 출력의 ARN 값으로 바꾸세요. 리전을 사용자의 리전으로 바꾸세요.

  2. 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-poo 명령을 실행하세요. 리전을 사용자의 리전으로 바꾸세요.

  3. 사용자 지정 이메일 발신자 Lambda 트리거를 사용하도록 Amazon Cognito 사용자 풀을 업데이트하세요. UpdateUserPool API의 CustomEmailSender 파라미터를 설정하세요. UpdateUserPool에 사용자 풀의 기존 파라미터와 변경하려는 파라미터가 모두 필요합니다. Amazon Cognito는 누락된 파라미터의 값을 기본값으로 설정합니다. 자세한 내용은 사용자 풀 구성 업데이트를 참고하세요.
    다음 예시의 경우 CustomEmailSender Lambda 함수 세부 정보와 함께 --lambda-config 파라미터만 사용되었습니다. 따라서 명령은 사용자 풀에 사용자 지정 이메일 발신자 트리거를 추가하고 나머지 사용자 풀 매개 변수를 기본값으로 설정합니다. 기본값이 아닌 값으로 사용자 풀을 구성하는 경우 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

    참고: LambdaARNcreate-function 명령 출력의 함수 ARN 값으로 바꾸세요. KMSKeyARNcreate-key 명령 출력의 ARN 값으로 바꾸세요. UserPoolId를 Amazon Cognito 사용자 풀 ID로 바꾸세요. 리전을 사용자의 리전으로 바꾸세요.

기능 테스트

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 로그 그룹에서 전체 로그를 볼 수 있습니다. 이 로그를 보는 방법에 대한 자세한 내용은 AWS Lambda와 Amazon CloudWatch 사용을 참고하세요.
@aws-crypto/client-node와 base64-js 모듈을 설치해 AWS Encryption SDK를 사용하세요.

AWS 공식
AWS 공식업데이트됨 10달 전