Django | 클래스 101 클론 - 네이버 OPEN API (문자인증)

김민철·2021년 1월 24일
1

팀프로젝트

목록 보기
4/8
post-thumbnail

이번 클래스 101 클론 프로젝트에서는 회원가입에 문자인증이 들어갑니다.

네이버 문자인증 서비스를 사용하며, 처음으로 OPEN API 를 적용해봤습니다.

from my_settings import (
                            serviceId,
                            AUTH_SECRET_KEY,
                            AUTH_ACCESS_KEY,
                            SMS_SEND_PHONE_NUMBER,
                            SECRET,
                            ALGORITHM,
)

#SMS 보내기
class SMSVerificationView(View):

    def send_verification(self, phone, code):
        SMS_URL = 'https://sens.apigw.ntruss.com/sms/v2/services/' + f'{serviceId}' + '/messages'
        timestamp = str(int(time.time() * 1000))
        secret_key = bytes(AUTH_SECRET_KEY, 'utf-8')

        method = 'POST'
        uri = '/sms/v2/services/' + f'{serviceId}' + '/messages'
        message = method + ' ' + uri + '\n' + timestamp + '\n' + AUTH_ACCESS_KEY

        message = bytes(message, 'utf-8')

				
# 알고리즘으로 암호화 후, base64로 인코딩
        signingKey = base64.b64encode(
            hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())

        headers = {
            'Content-Type': 'application/json; charset=utf-8',
            'x-ncp-apigw-timestamp': timestamp,
            'x-ncp-iam-access-key': AUTH_ACCESS_KEY,
            'x-ncp-apigw-signature-v2': signingKey,
        }

        body = {
            'type': 'SMS',
            'contentType': 'COMM',
            'countryCode': '82',
            'from': f'{SMS_SEND_PHONE_NUMBER}',
            'content': f'인녕하세요. ac101 입니다. 인증번호 [{code}]를 입력해주세요.',
            'messages': [
                {
                    'to': phone
                }
            ]
        }

# body를 json으로 변환
        encoded_data = json.dumps(body)
		
# post 메서드로 데이터를 보냄
        res = requests.post(SMS_URL, headers=headers, data=encoded_data)
        return HttpResponse(res.status_code)

    def post(self, request):
        try:
            data = json.loads(request.body)
            phone = data['phone']

            code = str(randint(100000, 999999))

			#update_or_creaete(조건, defaults = 생성할 데이터 값)
            PhoneVerification.objects.update_or_create(
                phone=phone,
                defaults={
                    'phone': phone,
                    'code' : code
                }
            )
						
	# phone, code 를 인자로 send_verification 메서드를 호출
            self.send_verification(
                phone=phone,
                code=code
            )
            return JsonResponse({'message': 'SUCCESS'}, status=201)


        except KeyError as e:
            return JsonResponse({'message': f'KEY_ERROR: =>  {e}'}, status=400)

        except ValueError as e:
            return JsonResponse({'message': f'VALUE_ERROR: =>  {e}'}, status=400)


# 문자인증 확인과정
class SMSVerificationConfirmView(View):

    def post(self, request):
        try:
            data = json.loads(request.body)
            phone = data['phone']
            verification_number = data['code']

            if verification_number == PhoneVerification.objects.get(phone=phone).code:
                if not User.objects.filter(number=phone).exists():
                    User.objects.create(number=phone)
                    return JsonResponse({'message': 'SUCCESS'}, status=200)

                else:
                    return JsonResponse({'message': 'REGISTERED_NUMBER'}, status=401)
            return JsonResponse({'message': 'INVALID_NUMBER'}, status=401)

        except KeyError as e:
            return JsonResponse({'message': f'KEY_ERROR: =>  {e}'}, status=400)

        except ValueError as e:
            return JsonResponse({'message': f'VALUE_ERROR: =>  {e}'}, status=400)

class SMSVerification 가 실행되면 post 메서드에서 랜덤코드를 생성하고 전화번호와 코드를 send_verification 메서드로 호출합니다. 그러면 send_verification 메서드는 네이버 클라우드 플랫폼에서 발급받은 인증키와 인코딩한 시크릿 키 등을 헤더에 담아 네이버 서버로 보냅니다. 서버는 키를 검증하고 유효시, SMS API를 호출하게 됩니다. 그리고 body의 데이터에 따라 문자를 보내줍니다.

문자를 보내면서 문자인증 db 에 전화번호와 인증코드를 저장하고, 클라이언트로 부터 넘어온 인증코드가 맞는지 확인하는 작업을 가집니다. 인증번호가 일치하고, 유저 db 에 데이터로 받은 전화번호가 없다면 유저db 에 번호를 저장합니다.

참고 : 네이버 API 가이드, 네이버 SMS API

0개의 댓글