django
카카오 로그인 (BackEnd)
베스트오버
2023. 6. 15. 09:07
1. 프론트에서 카카오톡에 연결해 코드를 받는다.
2. 프론트에서 준 코드로 카카오톡의 token을 받는다.
def get(self, request):
code = request.GET.get('code')
kakao_token_api = 'https://kauth.kakao.com/oauth/token'
data = {
'grant_type' : 'authorization_code',
'client_id' : KAKAO_REST_API_KEY,
'redirection_url' : KAKAO_REDIRECT_URL,
'code' : code,
'client_secret' : KAKAO_SECRET_KEY,
}
headers = {'Content-type': 'application/x-www-form-urlencoded;charset=utf-8'}
token_response = requests.post(kakao_token_api, data=data, headers=headers)
access_token = token_response.json().get('access_token')
expires_in = token_response.json().get('expires_in')
refresh_token = token_response.json().get('refresh_token')
refresh_token_expires_in = token_response.json().get('refresh_token_expires_in')
3. 카카오톡 토큰으로 유저 정보를 받아 DB에 저장한다.
user_data = requests.post(
"https://kapi.kakao.com/v2/user/me",
headers={
"Content-type": "application/x-www-form-urlencoded;charset=utf-8",
"Authorization": f"Bearer {access_token}",
# "Access-Control-Allow-Origin": "http://127.0.0.1:5500/kakao.html",
},
)
user_data = user_data.json()
email = user_data.get("kakao_account").get("email")
sns_id = user_data.get('id')
nickname = user_data.get('properties').get('nickname')
profile_image = user_data.get('properties').get('profile_image')
kakao_data = {
"email" : email,
"login_type": "kakao",
"sns_id" : sns_id,
"nickname" : nickname,
"profile_image" : profile_image,
"access_token" : access_token,
"expires_in" : expires_in,
"refresh_token" : refresh_token,
"refresh_token_expires_in" : refresh_token_expires_in,
}
try:
kakao_user, created = User.objects.get_or_create(email=email, defaults=kakao_data)
if created:
message = "신규 유저 정보 생성!"
response_status = status.HTTP_200_OK
else:
serializer = UserSerializer(kakao_user, data=kakao_data, partial=True)
if serializer.is_valid():
serializer.save()
message = "기존 유저 정보 업데이트!"
response_status = status.HTTP_200_OK
else:
return Response({"message": {serializer.errors}}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({"message": "DB 저장 오류입니다."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
4. JWT 토큰을 커스텀해서 발급해준다.
kakao_user = User.objects.get(email=email)
token = MyTokenObtainPairSerializer.get_token(kakao_user)
# JWT 토큰을 문자열로 변환
access_token = str(token.access_token)
refresh_token = str(token)
# OpenID connect 사용해요?
# 오류 등을 try 로 나누고 return이나 response도 나누기
# response에 답기
response_data = {'message': message, 'access_token': access_token, 'refresh_token': refresh_token}
return Response(response_data, status=response_status)