팀에서 운영하는 프로젝트중 하나는 Serverless 기반으로 백엔드를 구성하여 서비스하고 있습니다. 이 서비스에서 Backend API별 호출 빈도를 확인하는 로직이 필요하게 되었고 모든 API가 람다로 구성되어 있기 때문에 각 API의 호출 빈도를 알기 위해서 CloudTrail을 통해 특정 람다 그룹의 호출 로그를 확보하여 CloudWatch로 전송후 CloudWatch Insight로 분석하는 아키텍쳐로 문제를 해결하였습니다.

우선 이 포스트에서는 특정 이름으로 시작되는(특정 프로젝트의) 람다의 CloudTrail 로깅을 설정하고 이를 CloudWatch로 전송하는 솔루션과 그 CloudFormation 템플릿을 공유하려 합니다.

아키텍쳐 다이어그램

자세히 보기

AWS Rekognition을 사용해서 사업자등록증 검증하기

사업자 등록증을 처리

웹사이트에 구축한 플랫폼의 백엔드 작업중 프론트엔드 유저가 사업자등록증을 올렸을때 올바른 사업자등록번호인지를 검증하는 로직이 필요하게 되었다. 회사명 및 주소등의 정보는 필요가 없었고 단지 사업자 번호가 올바른지를 검증하면 되는 간단한 작업이었고 AWS Rekognition을 사용하여 처리한 경험을 간단히 공유하고자 한다.

참고로 Lambda 및 API Gateway는 Serverless를 통해 배포하였기 때문에 여기서는 생략하고 람다 내용만 공유한다.

우선 아키텍쳐 다이어그램을 보자

간단한 아키텍쳐 다이어그램

대략적인 워크플로우는 다음과 같다.

  1. API Gateway를 통해 제공되는 REST API를 통해 이미지를 업로드한다.
  2. Lambda에서 이미지를 AWS Rekognition에 보내 사업자 등록번호를 뽑아온다.
  3. 사업자 등록번호가 올바른 번호인지 검증한다.
  4. 검증 통과시 metadata 및 적절한 Key를 부여하여 S3에 업로드 한다.

AWS Lambda 구현

Lambda는 Javascript로 작성하였으며 다음 기능으로 구성되어 있다.

  1. 이미지를 파싱하고 원본 파일명을 저장

  2. 파싱한 Rekognition에 요청하여 Text 검출

  3. 검출된 Text중 사업자등록번호를 검출

  4. 사업자 등록번호가 검출되었을 경우 이미지에 메타데이터로 세팅하고 S3업로드

    ... 생략
    
    //버킷명은 환경변수에 세팅되어 있다.
    const bucketName = process.env.file_bucket_name;
    
    var input = JSON.parse(event.body);
    //무작위로 파일 키를 생성하기 위해 현재 시간 타임스탬프를 기준으로 키를 만든다.
    
    let key = moment().valueOf() + ""
    
    //base64로 인코딩 된 이미지를 버퍼에서 받아온다.
    const buf = Buffer.from(input.data, "base64");
    
    //등록번호는 우선 undefined
    let companyId = undefined;
    
    //AWS Rekognition
    const rekognition = new AWS.Rekognition();
    //인식을 요청하기 위한 파라메터. 받아온 이미지를 넣어준다.
    const params = {
        Image: {
            Bytes: buf
        },
    };
    
    const detectedTexts = await rekognition.detectText(params).promise();
    
    //찾아낸 텍스트들을 돌면서 사업자등록번호를 뽑는다.
    detectedTexts.TextDetections.forEach((item, index) => {
    
        const detectedText = item.DetectedText;
        //사업자등록번호인지 체크
        if (checkCorporateRegistrationNumber(detectedText)) {
            companyId = detectedText;
        }
    });
    
    //companyId가 undefined라면, 즉 아직 올바른 사업자등록번호를 못 찾았다면,
    if(!companyId){
       //...생략
       //에러 메세지 처리
    }
    //이미지 업로드
    
    //원본 파일명. 다운로드할때 필요하다.
    const filename = input.filename;
    
    //메타데이터 세팅. 원본 파일명과 사업자등록번호를 넣어준다.
    let metaData = {
        //한글 파일명등의 처리를 위해서 Base64 인코딩을 꼭 해주어야 한다. 
        "filename": Base64.encode(filename),
        "company_id":companyId
    }
    
    var data = {
        Bucket: bucketName,
        Key: key,
        Body: buf,
        Metadata: metaData
    
    };
    //S3로 업로드
    try {
        await s3.putObject(data).promise()
    } catch (e) {
        console.log(e);
        //에러 처리
    }
    .. 생략

사업자 등록번호를 검증하기 위한 로직은 “Mr.latte” 님의 블로그에서 참고하여 사용하였다.

    //https://www.mrlatte.net/code/2019/01/21/check-corporate-registration-number.html
    function checkCorporateRegistrationNumber(value) {
        var valueMap = value.replace(/-/gi, '').split('').map(function (item) {
            return parseInt(item, 10);
        });

        if (valueMap.length === 10) {
            var multiply = new Array(1, 3, 7, 1, 3, 7, 1, 3, 5);
            var checkSum = 0;

            for (var i = 0; i < multiply.length; ++i) {
                checkSum += multiply[i] * valueMap[i];
            }

            checkSum += parseInt((multiply[8] * valueMap[8]) / 10, 10);
            return Math.floor(valueMap[9]) === (10 - (checkSum % 10));
        }
        return false;
    }

아쉬운점

사업자 등록증의 상호명, 주소 등등의 내용은 가져올 수 없었다. 왜냐하면 AWS Rekognition 자체에서 한국어를 지원하지 않기 때문이다.

AWS의 여러 ML 관련 서비스는 영어 컨텐츠에 대해서는 어마무지한 성능을 보여주나 한국어는 아직 네이버 등과 같은 우리나라 서비스들과 비교해서 볼품없는 것 같다. AWS Transcribe, AWS Rekognition, AWS Comprehend 등 여러 서비스들의 한국어 지원이 미흡한 것이 사실이라 차차 한국어를 지원하는 서비스들이 늘어나기를 기대해본다.

WRITTEN BY
Dev Lead | Certified Professional AWS Solutions Architect/Devops Engineer