Kakao 로그인 사용자 정보 받기

0

프로젝트 일지와 독립적으로 기록하여 기억해두기

1. 큰 흐름

도대체 어떻게 통신하는가??

1. 프론트엔드와 카카오의 로그인 플로우

  1. 카카오에 로그인한다.
  2. 카카오 API에서 프론트엔드로 인가코드를 준다.
  3. 인가코드를 받은 프론트엔드가 카카오 API에게 access token을 요청한다.
  4. 카카오 API가 엑세스 토큰을 프론트엔드에게 준다.
  5. 그걸 받은 프론트엔드가 POST를 통해 백엔드에게 헤더에 담아 엑세스 토큰을 준다.(Authorization)

2. 프론트와 벡엔드의 토큰 플로우

  1. 백엔드는 request를 통해 헤더에 있는 토큰을 get한다.
  2. requests.get을 통해 엑세스 토큰의 헤더 내용을 온전히 받아 읽는다.

    여기서 http로 파이썬의 request를 하는 부분이 나오는데 이 부분을 잘 몰라서 한참 헤맸다.

  3. 이후 받은 토큰을 json을 통해 깐다.
  4. 필요한 유저 정보를 얻는다.
  5. 이후 회원가입을 했는지 안 했는지 여부에 따라 토큰을 가입시키고 줄지, 로그인이 된 상태에서 줄지를 결정한다.

2. 알았어야 할 이론들

1. 토큰이 담긴 곳, POST인 이유

  • 토큰이 담긴 곳은 당연히 헤더스다. 실제로 맞춰볼 때도 바디에 담겨서 왔었던 적이 있어 제대로 구현이 안 되기도 했다.

  • POST인 이유:
    GET과의 차이점이 드러나는 부분인데 GET은 단순히 데이터를 받아오는기만 하는 것이지 위 과정처럼 토큰을 생성하거나 수정하는 등의 과정이 있을 때는 POST를 쓰는 거이 옳다.

  • 큰 차이 : 바디가 있냐 없냐도 차이가 있다.

2. 파이썬의 requests

  • 카카오 디벨로퍼 홈페이지에서는 이렇게밖에 나오지 않는다.

이걸 보고 대체 어떻게 하란건지 처음에 굉장히 난처했다. 하지만 http가 어떻게 requests를 통해 송수신 되는지 확인한 결과

공식문서ㅓ

헤더스를 어떻게 위치 시키고 하는지 활용하여 get할 수 있었다.

  • 이를 장고로 계속 찾아서 해답이 없었던 것

3. 온 데이터의 형태와 가공

물론 이는 print를 찍어보면 알겠지만 {{}}형태의 데이터로 온다. 이를 필요한 데이터만큼 []를 이용하여 추출하면 된다.

3. 최종 코드

  • 아직 모자란 점 : 데코레이터 처리를 하지 않음
  • 유닛 테스트 하지 않음

    이는 추후 과제로 두고 정리부터 하면 다음과 같다.

import json
import bcrypt
import jwt
import requests

from django.shortcuts       import redirect
from django.views           import View
from django.http            import JsonResponse, HttpResponse
from django.core.exceptions import ObjectDoesNotExist
from django.db              import IntegrityError

from my_settings import SECRET_KEY, HASHING_ALGORITHM
from .models     import User, Creator


class KakaoSignInView(View):
    def post(self,request):
        try:
            access_token = request.headers.get('Authorization')
            user_profile = requests.get(
                'https://kapi.kakao.com//v2/user/me', 
                headers={'Authorization' : 'Bearer {}'.format(access_token)}
                )
            json_user_profile = user_profile.json()
            kakao_id   = json_user_profile['id']
            nickname   = json_user_profile['properties']['nickname']
            user_email = json_user_profile['kakao_account']['email']
            if not User.objects.filter(kakao_id = kakao_id): 
                username = User.objects.create(
                    username = nickname,
                    email    = user_email,
                    kakao_id = kakao_id
                )
                new_token = jwt.encode({'username_id' : username.id}, SECRET_KEY, algorithm=HASHING_ALGORITHM)
                return JsonResponse({'message' : "SIGN_IN_SUCCESS",'new_token' : new_token},status=200)
            username = User.objects.get(kakao_id=kakao_id)
            new_token = jwt.encode({'username_id' : username.id}, SECRET_KEY, algorithm=HASHING_ALGORITHM)
            return JsonResponse({'message' : "LOGIN_SUCCESS", 'new_token' : new_token}, status=200)
        except KeyError:
            return JsonResponse({"message" : "KEY_ERROR"}, status=400)
        except ObjectDoesNotExist:
            return JsonResponse({"message" : "USER_DOES_NOT_EXIST"}, status=400)
profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

1개의 댓글

comment-user-thumbnail
2021년 12월 16일

고맙습니다 엉엉....

답글 달기