카카오 로그인 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
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)
👍