ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DRF - SMS] 네이버 SMS 문자 인증 구현하기
    한이음 프로젝트 2023. 9. 5. 13:00

    현재 프로젝트에서는 azure 클라우드 서비스를 이용하는데 무지했던 나는 인터넷을 뒤져보다가 네이버 클라우드를 활용한 sms 문자 인증이 좋다는 것을 듣고 이것으로 했다.. azure로 해볼껄 그랬당..


    1. 네이버 플랫폼 필요사항.

    2. model.py 작성

    3. view.py(+util.py) 작성

    4. url.py 작성

    5. postman 실습


     

    1.1 Naver cloud에서 Simple & Easy Notification Service를 클릭한다.

    -> Simple & Easy Notification Service 바로가기

     

     

    NAVER CLOUD PLATFORM

    cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification

    www.ncloud.com

     

    1.2 프로젝트를 생성합니다.(서비스 타입과 이름을 정합니다.)

     

    1.3 발신번호를 등록합니다.( sms -> Calling Number -> 발신번호 등록 -> 본인인증)

    1.4 콘솔이 아닌 포털로 가서 API 인증키를 생성합니다.

       (마이페이지 -> 계정관리 -> 인증키 관리 -> 신규 API 인증키 생성성하기)

     

     

    이로써 네이버 플랫폼에서 필요한 요구사항은 끝났음.


    2.1 model.py 작성

     

    나는 phone-번호는 일단 하나밖에 없는 번호이기 때문에, PK를 phone으로 잡았는데 그냥 phoneIdx로 해서 인덱스 값으로 줄껄 그랬다. (아직.. 초보라)

       
    class Auth(models.Model):
        phone = models.CharField(max_length=11, primary_key=True, blank=True)
        username = models.TextField(blank=True)
        auth = models.IntegerField(blank=True)
        created_at = models.DateTimeField(auto_now_add=True, blank=True)
        updated_at = models.DateTimeField(auto_now = True, blank=True)

        class Meta:
            db_table = 'auth_sms'
       

     

     

    -> 여기서 blank =True 라는 것은 사용자가 입력을할때 이 필드를 빈값으로 허용한다는 뜻이다.

    - db_table = 'auth_sms' : 테이블으 이름을 auth_sms로 한다는 뜻임.


    3.1 view.py 작성

     

    기본적으로 네이버에서 제공하는 SMS API - API 참조서를 참고했고 다른 블로그들을 찾아보면서 코드를 완성함.

    SMS API (ncloud-docs.com)

     

    SMS API

     

    api.ncloud-docs.com

     

    <view.py>

       
        #sms 보내기 api
                   
    class SmsSendView(APIView):
        def send_sms(self, phone, auth):
           
            timestamp = str(int(time.time() * 1000))  
           
            headers = {
                'Content-Type': "application/json; charset=utf-8", # 네이버 참고서 차용
                'x-ncp-apigw-timestamp': timestamp, # 네이버 API 서버와 5분이상 시간차이 발생시 오류
                'x-ncp-iam-access-key': '[my Access key]', #나의 Access key
                'x-ncp-apigw-signature-v2': make_signature(timestamp) # utils.py 이용
            }
           
            body= {
                "type": "SMS",
                "contentType": "COMM",
                "from": "01012345678", # 사전에 등록해놓은 발신용 번호 입력, 타 번호 입력시 오류
                "content":f"[인증번호:{auth}]", # 메세지를 이쁘게 꾸며보자
                "messages": [{"to": f"{phone}"}] # 네이버 양식에 따른 messages.to 입력
            }
            body = json.dumps(body)

            requests.post('url + uri ', headers=headers, data=body)
       
        def post(self, request):
            data = request.data
            try:
                input_mobile_num = data["phone"] #phone번호를 가져온다. 입력한
                auth_num = random.randint(1000, 10000) # 랜덤숫자 생성, 4자리로 계획하였다.
                auth_mobile = Auth.objects.get(phone=input_mobile_num)
                auth_mobile.auth= auth_num #인증번호를 db에 넣음.
               

                auth_mobile.save()
                self.send_sms(phone=input_mobile_num, auth=auth_num) #인증번호 보내기 호출
                response_data = {'message' : '인증번호를 보냈습니다.'}

            except Auth.DoesNotExist:
                Auth.objects.create(
                    phone=input_mobile_num,
                    username=data["name"],
                    auth=auth_num,
                ).save()
                self.send_sms(phone=input_mobile_num, auth=auth_num)
                response_data = {'message' : '인증번호를 보냈습니다.'}
       
            return Response(response_data, status=status.HTTP_200_OK)
     

    근데 지금 와서 생각해보니 def sms_send()를 따로 함수로 뺴서 구현해둘 껄 그랬다. 뭐 그렇다

     

    3.2 util.py 작성

       
    import hashlib
    import hmac
    import base64

    def make_signature(timestamp):
        access_key = '[MY ACCESS KEY]'
        secret_key = '[MY SECREY KEY]'
       
        secret_key = bytes(secret_key, 'UTF-8')

        uri= '/sms/v2/services/프로젝트 생성시 주는 service Id값 /messages'

        message = "POST" + " " + uri + "\n" + timestamp + "\n" + access_key
        message = bytes(message, 'UTF-8')
        signingKey = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())
        return signingKey
       

     

    util.py를 해당 앱에 추가를 해서 해당 코드를 작성합니다.

    이 값을 service id에 적음

     

    url 값은 : https://sens.apigw.ntruss.com

    uri 값은 : '/sms/v2/services/프로젝트 생성시 주는 service Id값 /messages'

    https://sens.apigw.ntruss.com/sms/v2/services/{serviceId}/messages

    즉 이것을 uri+url 값으로 적으면 됨.

     


    4. url.py 작성

    url.py에 해당 url를 추가해준다.

        path('users/auth',views.SmsSendView.as_view()),

     


    5. postman 실습

     

    완료했다. 해당 응답값은 이런식으로 나오는데 이건 미들웨이 설정을 해놔서 이렇게 나온다. 이것에 대해서는 나중에 다뤄보기로 합니다. 이미 열심히 만들어둔 코드를 이제서야 올리는 것이라,.... 

     

    +) 인증번호가 온 값을 인증하기

     

    1) view.py 작성하기


    # 네이버 SMS 인증번호 검증
    class SMSVerificationView(APIView):
        def post(self, request):
            data = json.loads(request.body)

            try:
                verification = Auth.objects.get(phone=data['phone'])

                if verification.auth == data['auth']:
                    response_data = {'message': "인증이 완료되었습니다."}
                    return Response(response_data, status=status.HTTP_200_OK)


                else:
                    response_data = {'auth':["인증번호가 일치하지 않습니다."]}
                    return Response(response_data, status=status.HTTP_400_BAD_REQUEST)

            except Auth.DoesNotExist:
                    response_data = {'auth':["해당 번호에 대한 정보가 없습니다."]}
                    return Response(response_data, status=status.HTTP_404_NOT_FOUND)
       

    2) postman으로 실습하기

     

    완료하였음. 다음에는 로그인 id 찾기 기능을 만들어 볼 예정입니다.

     

    참고 문헌 

    [파이썬] 문자발송 API 완벽이해하기 ( feat. SENS, ncloud API) : 네이버 블로그 (naver.com)

    '한이음 프로젝트' 카테고리의 다른 글

    [DRF- User& sms인증] 아이디 찾기  (0) 2023.09.12
    [DRF - User] 로그인 API  (0) 2023.08.21
    [DRF - User] 회원가입 API  (0) 2023.08.21
    [DRF - User] 커스텀 User -1  (0) 2023.08.21
    DRF 공부( python)  (0) 2023.07.31
Designed by Tistory.