import jwt
import requests
from json.decoder import JSONDecodeError
from django.http import JsonResponse
from django.views import View
from users.models import User
from my_settings import SECRET_KEY, ALGORITHMS
class KakaoLogin(View):
def get(self, request):
try:
# kakao token 받기 / 유효성 검사를 합니다.
token = request.headers.get('Authorization')
if token == None:
return JsonResponse({'messsage': 'INVALID_TOKEN'}, status=401)
# kakao token을 다시 kakao로 보내서 유저 정보를 받아옵니다.
kakao_account = requests.get('https://kapi.kakao.com/v2/user/me', \
headers = {'Authorization': f'Bearer {token}'}).json()
# 받아온 kakao 유저정보중 id가 db에 있는지 확인합니다.
if not User.objects.filter(kakao_id=kakao_account['id']).exists():
# 유저 정보가 없으면 회원가입 되도록 합니다.
user = User.objects.create(
kakao_id = kakao_account['id'],
email = kakao_account['kakao_account']['email']
)
# kakao id를 통해 db에서 해당 유저 정보를 가져옵니다.
user = User.objects.get(kakao_id=kakao_account['id'])
# 유저의 id를 jwt를 통해 암호화하여 token에 실어줍니다.
access_token = jwt.encode({'user_id': user.id}, SECRET_KEY, algorithm=ALGORITHMS)
return JsonResponse({'access_token': access_token}, status=201)
except KeyError:
return JsonResponse({'message': 'KEY_ERROR'}, status=400)
except JSONDecodeError:
return JsonResponse({'message': 'JSON_DECODE_ERROR'}, status=400)
except jwt.DecodeError:
return JsonResponse({'message': 'JWT_DECODE_ERROR'}, status=400)
except ConnectionError:
return JsonResponse({'message': 'CONNECTION_ERROR'}, status=400)
kakao_account = requests.get('https://kapi.kakao.com/v2/user/me', \
headers = {'Authorization': f'Bearer {token}'}).json()
FE로부터 받아온 kakao token이 있으면 kakao REST API를 통해
유저정보를 가져올 수 있습니다.
🥕 kakao developers 카카오 로그인 REST API 사용자정보 가져오기 https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#req-user-info
if not User.objects.filter(kakao_id=kakao_account['id']).exists():
user = User.objects.create(
kakao_id = kakao_account['id'],
email = kakao_account['kakao_account']['email']
)
kakao에서 가져온 유저정보를 통해 db에 접근하여 일치하는 kakao 정보가 있는지
조회하고 없는 경우 정책에 따른 유저 정보를 db에 저장시켜 회원가입으로 연결시킵니다.
유저가 카카오 로그인을 시도하는 것 자체가 해당 사이트 회원가입에 대한 의지가
있는 것이기 때문에 자연스럽게 회원가입이 되도록 하였습니다.
user = User.objects.get(kakao_id=kakao_account['id'])
access_token = jwt.encode({'user_id': user.id}, SECRET_KEY, algorithm=ALGORITHMS)
return JsonResponse({'access_token': access_token}, status=201)
카카오 로그인으로 가입한 회원은 kakao id를 가져와 저장하였기 때문에
해당 id로 회원정보를 가져오도록 하였습니다.
만약 사이트 자체 회원가입 기능이 있다면 그냥 email로 회원조회 기준을
통일하는 것도 좋을 것 같습니다.
조회된 회원정보를 바탕으로 유저의 id를 가져와 jwt를 통해 암호화 및
토큰을 생성하여 FE에게 전송해 주게 됩니다.