[django] 카카오 로그인 views.py

DanChu 🌟·2021년 3월 7일
2

웹사이트에서 별도의 회원가입 절차 없이 카카오 계정으로 바로 로그인을 할 수 있는 기능을 구현함.

필요한 정보는 kakao developers에 다 나와있지만, 처음 들어갔을땐 페이지에 정보가 많아서 어디서 어떤 정보를 찾았는지 좀 헷갈림..

일단 kakao developers 페이지로 들어가서 상단에 My application으로 가서 작업 할 app을 추가

이후 생성한 app을 클릭하면 아래같은 정보가 담긴 페이지가 뜸.

여기서 REST API Key 값이 중요한데, 노출되면 안되는 정보이니 my_settings.py에 보관하는 것이 좋다.

카카오 로그인의 flow를 간단히 설명하면:

  1. 웹페이지에 접속한 사용자가 '카카오로 로그인하기'를 클릭
  2. 카카오 로그인페이지가 뜨고 로그인시 해당 사용자에 대한 token이 프론트앤드로 날아옴
  3. 프론트에서 이 token 을 백엔드로 넘겨줌
  4. 백엔드에서 이 token을 들고 kakao에 다시 요청을 날리는데, 이 요청이 해당 사용자에 대한 개인정보들 eg) email, 이름 등
  5. 해당 token이 유효하면 카톡에서 사용자 정보를 보내줌

카카오로는 총 두번의 request가 우리 웹사이트에서 날아가게되는데, 첫번쨰는 front에서 그리고 두번째는 back에서 간다.

지금 작성은 backend기준이기때문에, 3번까지 완료가된 상태라는 가정에서 이젠 백에서 카카오로 요청을 보낼 views.py를 작성하면 된다.

어떤 형태로 request를 보내야할지 모르면 아래를 참고:

메인페이지로 돌아오면 kakao login 카드가 있는데 여기서 Read docs를 클릭.

왼쪽 메뉴바에서 'REST API'를 클릭 후 REST API Test Tool 클릭

오른쪽 끝에 메뉴버튼을 눌러서 작업하는 앱으로 변경

스크롤을 내리면 request 부분이 있는데 이곳에서 프론트가 요청시 받을 token을 직접 생성해볼 수 있다.

access token 선택 후, issue token 클릭!

token이 생성되었으면 조금 더 스클롤 내려서 send 버튼 클릭.

그러면 아래에 response라는 곳에서 back에서 요청을 보내야 할 주소와 형식을 보여주고, 해당 요청이 왔을경우 어떤 결과값이 backend로 다시 전달되는지를 볼 수 있다.

이걸 참고해서 다시 views.py작성으로 돌아오면,

access_token = request.headers['Authorization']
url          = "https://kapi.kakao.com/v2/user/me"
header       = {
                'Authorization' : 'Bearer {}'.format(access_token)
            }
response     = requests.get(url, headers = header).json()

이것만 추가해주면 response에 카카오에서 보내준 사용자 정보가 담긴다.

access_token은 Authorization이름으로 딸려올 front 에서 받은 토큰이 담기고, url은 백엔드에서 요청을 보내야하는 주소이다. header는 해당 요청 시 함께 딸려보내는 토큰으로, 프론트에서 받은 토큰을 카카오에서 원하는 형식에 맞추어 header에 담는 과정.

이렇게 준비가 되면 get요청을 url 주소로, header정보를 담아 보내는 것 (좀 전에 카카오에 요청을 보낼때 형식 example처럼 맞춰서 request 전송), 카카오에서 보낸 결과값이 response에 담기는것으로 카카오와 통신은 끝!

이후에 response에 담겨온 결과값을 가지고 내 model에 맞게 사용하면 끝.

내 완성코드:

class KakaoSignInView(View):

    def get(self, request):
        try:
            access_token = request.headers['Authorization']
            url          = "https://kapi.kakao.com/v2/user/me"
            header       = {
                'Authorization' : 'Bearer {}'.format(access_token)
            }
            response     = requests.get(url, headers = header).json()
                
            if 'email' not in response['kakao_account']:
                return JsonResponse({'message': 'EMAIL_REQUIRED'}, status = 405)

            user, is_user = User.objects.get_or_create(
                email         = response['kakao_account']['email'], 
                profile_image = response.get('kakao_account''profile''profile_image_url', None),
                fullname      = response['kakao_account']['profile']['nickname']
            )

            token = jwt.encode({'id': user.id}, SECRET_KEY, algorithm=ALGORITHM)
            result = {
                'profile_image' : user.profile_image,
                'name'          : user.fullname
                }
            
            return JsonResponse({'message': 'SUCCESS', 'data': result, 'token': token}, status = 200)

        except:
            return JsonResponse({'message': 'TOKEN_INVALID'}, status=401)

0개의 댓글