AWS Cognito Third-party SMS 사용하기

이선주·2024년 2월 4일
0

aws

목록 보기
1/1

AWS Cognito에서 전화번호 인증은 기본적으로 Amazon SNS서비스를 사용하여 SMS 인증 메시지를 발송합니다. 요금은 다음과 같습니다.

2024.01.19 환율: $0.02414 = ₩32.26

Amazon SNS는 한국에서의 비용이 너무 비싸다고 생각해서 국내 SMS API를 사용하고자 합니다. 때문에 Cognito에서 인증 SMS 메시지를 발송할 때 Third-Party API 연동하는 방법을 알아보겠습니다.


서버리스 구성

기본 SMS 메시지 발송 방식

SMS API를 이용하여 Cognito 인증 코드를 발송하기 위해서는 Lambda 함수로 메시지 발송을 구현해야 합니다. 구현된 함수는 Cognito의 "SMS 발신자 트리거" 와 연동합니다.

SMS 발신자 트리거는 Cognito에서 인증 메시지를 발송할 때마다 Lambda 함수를 실행하게 해주는 트리거입니다.

CustomSMSSender 트리거로 Lambda 함수를 실행하여, Third-Party API와 연동

이를 통해 Amazon SNS로 SMS 메시지를 발송하는 것이 아닌, Lambda 함수를 트리거하여 Third-party SMS API와 연동된 저희만에 메시지를 발송합니다.


Third-Party API 연동

이제 본격적으로 Cognito Trigger: CustomSMSSender로 Lambda 함수를 트리거하여 Third-Party API를 호출해보겠습니다.

AWS Cognito가 이미 생성되어 있다는 가정하에 진행하겠습니다.

1. AWS KMS: 대칭 암호화 키 생성

AWS Cognito는 SMS 메시지로 발송할 인증 코드를 생성한 다음 KMS 키를 사용하여 암호화합니다. 암호화된 인증 코드를 복호화하기 위해 우선 대칭 암호화 키를 생성합니다.

생성된 키를 이용하여 Cognito가 인증 코드를 암호화하고 Lambda 함수에서 복호화하기 위함입니다.

고객 관리형 키 생성

생성할 키는 대칭 암호화 키입니다. 키 구성은 "대칭"으로 선택해주세요.

키 유형은 "대칭" 암호화 키

키 사용자를 선택합니다. 반드시 Lambda 함수를 실행할 IAM 사용자 또는 역할을 선택해주세요.

다음은 정책입니다. 정책은 특정 사용자에게 리소스에 대한 접근을 허용합니다. 해당 정책의 경우, AWS Cognito가 인증 코드를 암호화하는데 있어 KMS 키 사용을 허가해주는 정책입니다.

해당 정책은 다음과 같이 추가하시면 됩니다.(${AWS_COGNITO_ARN} = Cognito 사용자 풀의 ARN을 찾아서 해당 부분을 교채해주세요.)

{
	"Sid": "Allow use of the key to Cognito",
	"Effect": "Allow",
	"Principal": {
		"Service": "cognito-idp.amazonaws.com"
	},
	"Action": "kms:CreateGrant",
	"Resource": "*",
	"Condition": {
		"ArnLike": {
			"aws:SourceArn": "${AWS_COGNITO_ARN}"
		}
	}
}

정책 구성 JSON

이제 해당 AWS Cognito 사용자 풀은 생성된 KMS 대칭 키를 이용하여 인증 코드 암호화합니다. 이제 Lambda 함수에서 암호화된 인증 코드를 복호화하여 Third-Party API를 호출하기만 하면 됩니다.

2. Lambda 함수 생성 및 트리거

AWS Cognito 사용자 풀에서 SMS 발송 이벤트가 발행되면, 아래 Lambda 함수를 실행하게 설정해 보겠습니다.

/**
 * Function Handler
 *
 * @param {import('aws-lambda').PreSignUpTriggerEvent} event
 */
export const handler = async (event) => {
  const receipient = event.request.userAttributes.phone_number;
  const nonce = '?';

  // Third-Party API에서 SMS 메시지를 발송합니다.
  // await ThirdPartyAPI.sendMessage(receipient, `인증 코드는 "{nonce}"`);

  return event;
};

우선 Lambda 함수를 생성합니다. 생성된 함수는 아래 명령어를 통해 Cognito에서 함수를 호출할 수 있게 권한을 설정합니다.

$ aws lambda add-permission \
               --function-name ${LAMBDA_ARN} \
               --statement-id "CognitoLambdaInvokeAccess" \
               --action lambda:InvokeFunction \
               --principal cognito-idp.amazonaws.com

함수 권한 설정 명령어

추가된 정책은 Lambda 함수에서 구성 탭으로 들어간 후 아래에 "리소스 기반 정책"에서 확인하실 수 있습니다.

그리고 Cognito 사용자 풀에서 CustomSMSSender 트리거를 사용할수 있도록 업데이트해야 합니다. 아래 명령어를 통해 Cognito 사용자 풀을 업데이트 해주세요.

$ aws cognito-idp update-user-pool \
                    --user-pool-id ap-southeast-2_LTCxu2J1g \
                    --lambda-config "CustomSMSSender={LambdaVersion=V1_0,LambdaArn=${LAMBDA_ARN}},KMSKeyID=${KMS_KEY_ARN}"

Cognito 사용자 풀에 Lambda 함수를 트리거로 설정 및 KMS 키 등록

SMS 발송 트리거와 Lambda 함수가 생성되었습니다.(Cognito 대시보드에서 확인가능)

이렇게 명령어가 성공하면 이제부터 해당 Cognito 사용자 풀에서 인증 메시지가 발송하면, 설정한 KMS 키를 이용해 인증 코드를 암호화하고 Lambda 함수를 트리거합니다.

CustomSMSSender 트리거로 Lambda 함수를 등록함과 동시에 KMS 키도 등록합니다.

성공적으로 Lambda 함수를 SMS 발신자로 등록되었습니다.

3. AWS Cognito 설정

Cognito 사용자 풀의 CustomSMSSender 트리거로 등록된 Lambda 함수가 제대로 작동하려면 대시보드에서 몇 가지 설정할 것들이 있습니다.

✔️ 속성 확인 및 사용자 계정 확인

Cognito 대시보드에서 > 사용자 풀 > 가입 경험 탭을 선택해줍니다.

  • Cognito 지원 확인 및 확인: Cognito가 자동으로 메시지를 발송할 수 있게 활성화 해주어야 합니다.
  • 속성 변경 확인: 사용자가 이메일 주소 또는 전화번호 속성을 업데이트하면 Amazon Cognito는 새 값을 확인할 때까지 이를 unverified로 표시합니다. 활성해줍니다.

✔️ AccessDeniedException: user is not authorized to perform kms:decrypt

CloudWatch에서 확인해보니 Lambda 함수 로그에 다음과 같은 에러를 확인했습니다.

ERROR Internal Server Error: Error: Unable to decrypt data key and one or more KMS CMKs had an error. Error

AccessDeniedException: User is not authorized to perform: kms:Decrypt on resource kms because no identity-based policy allows the kms:Decrypt action

해당 문제는 Lambda 함수가 KMS 키를 사용할 권한이 없을 때 발생하는 문제입니다.
저의 경우, AWS SAM CLI를 이용하여 배포된 Lambda 함수의 역할이 해당 KMS 키의 권한을 가지고 있지 않아서 발생하는 문제였습니다.

이 글을 잘 보신 분들은 눈치 채셨겠지만, KMS 키 생성 단계에서 "키 사용자(IAM)"를 잘못 선택하셨거나, 함수의 IAM이 다를 확률이 높습니다.

따라서 Lambda 함수를 실행하는 IAM 사용자 또는 역할에 KMS 키를 접근을 허용하는 정책을 추가해주면 됩니다.

"Lambda > 함수 > 본인 함수명에서 > 구성 탭 클릭"하면 실행 역할을 확인할 수 있습니다.

다음과 같이 Lambda 함수 실행 역할 IAM의 ARN을 정책으로 추가합니다.

profile
백엔드 개발자의 기초 다지기

0개의 댓글