Django에서 카카오API를 이용한 소셜로그인 기능 구현하기

juri·2021년 8월 22일
0

Django

목록 보기
11/11
post-thumbnail

카카오 소셜 로그인을 향한 나의 고뇌

참고 : kakao developers 카카오 로그인


전체적인 흐름


카카오 로그인 API를 이용한 소셜로그인 기능은 크게 세가지의 단계로 이루어진다.
1. 인증코드 받기
2. 인증코드로 토큰 받기
3. 받은 토큰으로 사용자정보 받기

보통 프론트엔드에서 1번과 2번을 수행한 후 카카오 서버로부터 받은 토큰을 백엔드 서버로 보내고, 백엔드에서 그 토큰으로 카카오로부터 사용자 정보를 받아온다. 더 자세하게 알아보자.


백엔드의 역할

프론트엔드와 분업을 어떻게 하냐에 따라 다르지만 보통 이렇게 분업을 한다고 하니 3번부터 설명한다. (실제론 모든 과정을 백엔드에서 해결할 수 있지만 이렇게 몰빵(?)하면 가끔 오류가 발생할 때가 있다고 한다.)

프론트엔드에서 요청메세지의 헤더에 카카오로부터 받은 토큰을 담아 백엔드 서버로 보내준다. 백엔드는 그 헤더를 받아 카카오서버로 보내 카카오서버에 저장된 사용자의 정보를 받아온다. DB에 저장된 사용자의 정보와 비교해 이미 정보가 저장된(이미 회원가입을 한) 사용자라면 토큰을 생성 후 프론트엔드로 반환, 정보가 없는 사용자라면 회원가입을 진행한 후(DB에 사용자 정보를 저장) 토큰을 생성해 프론트엔드로 반환한다.

사용자 동의

모든 사용자 정보와 서비스 접근권한은 사용자 동의가 있어야만 제공된다. [내 애플리케이션] > [카카오 로그인] > [동의 항목]에서 카카오 로그인 시 제 3자 정보제공 동의를 받을 항목들을 설정할 수 있다. 이메일을 받아오기 위해선 사용자의 동의가 필요한 데 사용자가 동의하지 않으면 이메일 정보를 받아올 수 없다(필수 동의로 설정하기 위해선 실제 사업자 등록하는 과정을 거쳐야 함) 그렇기때문에 모델링 구축할 때 이메일 필드를 null=True로 설정하는 것도 하나의 방법이다.

카카오서버로 요청메세지 보내기

카카오 사용자 정보 가져오기 API : https://kapi.kakao.com/v2/user/me
requests 모듈 관련 참고 : https://dgkim5360.tistory.com/entry/python-requests

requests 모듈을 이용해 카카오 서버로 요청한 응답 가져오기

response = requests.get(요청보내는 url, option)

option에는 파라미터, 헤더, 쿠키에 대한 정보를 담을 수 있다. response에는 지정한 url로 보낸 get 요청에 대한 응답이 담긴다. 카카오는 헤더에 담을 토큰의 양식을 지정하고 있다. 카카오에서 지정한 파라미터를 같이 보내면 그에 대한 응답만 돌아온다.

url           = 'https://kapi.kakao.com/v2/user/me'
response      = requests.get(url, headers={'Authorization': f'Bearer {access_token}'})
user_response = response.json()

이메일과 닉네임을 지정하는 파라미터(키값)은 아래와 같다.

['kakao_account']['email']
['properties']['nickname']

돌아온 response는 json의 형태로 변환한 후, 필요한 정보를 뽑아내 회원가입과 로그인을 진행한다. 이 후의 과정은 일반 로그인과 같다.


전체 코드

import json, jwt, requests, random

from django.http  import JsonResponse
from django.views import View

from users.models import User
from my_settings  import SECRET_KEY

class KakaoSignInView(View): 
    def get(self, request): 
        try:
            access_token = request.headers.get('Authorization')

            if not access_token: 
                return JsonResponse({'message':'no_token'}, status=401)

            url           = 'https://kapi.kakao.com/v2/user/me'
            response      = requests.get(url, headers={'Authorization': f'Bearer {access_token}'})
            user_response = response.json()
        
            user,created = User.objects.get_or_create(kakao_id=user_response['id'])

            if created: 
                user.email    = user_response['kakao_account']['email']
                user.nickname = user_response['properties']['nickname']
                user.point    = random.randrange(0,10000)
                user.save()

            token = jwt.encode({'id':user.id}, SECRET_KEY, algorithm= 'HS256')
            return JsonResponse({'TOKEN':token}, status=200)
        except KeyError:
            return JsonResponse({'message':'invalid_token'}, status=400)
        
profile
Make my day !

2개의 댓글

comment-user-thumbnail
2021년 8월 22일

👍

답글 달기
comment-user-thumbnail
2021년 8월 22일

아니 이주님 짤 너무 탐나네요;; 슬랙으로 매번 보내주세요;

답글 달기