Django - 카카오 소셜 로그인/회원가입 구현하기

김우식·2022년 7월 9일
0

소셜 로그인/회원가입을 해보자 with kakao

카카오 개발자 페이지 (카카오 로그인)
https://developers.kakao.com/docs/latest/ko/kakaologin/common

OAuth가 뭐지

카카오 소셜 로그인은 OAuth 2.0 프로토콜을 따라 진행된다.
기능 구현 이전에, OAuth 2.0을 먼저 공부해보자!

OAuth 2.0 동작방식의 이해(한컴 인텔리전스 블로그)

Step 1. 카카오 로그인 인증받기 / 카카오 Access_token 발급받기

카카오 소셜로그인을 하기 위한 첫번째 단계이다.
카카오 계정으로 카카오 서버에 인증,인가,토큰 발급을 진행하는 진행도이다.
이번 프로젝트에는 FE에서 토큰발급까지 진행 후, BE에 토큰을 전달하여
사용자 정보를 가져오는 flow로 진행하기로 기획하였다.
따라서, 토큰발급이후의 과정을 작성해보도록 하겠다.

Step 2. 회원확인 및 가입 / 서비스 로그인

다음 단계로 넘어가보자.
발급된 kakao access_token을 이용해 카카오 Api서버와 통신해야 한다.

class KaKaoSignUpView(View):
    def get(self, request):
        access_token     = request.headers.get('Authorization') #FE로부터 kakao_token 전달받기
        KAKAO_INFO_API   = 'https://kapi.kakao.com/v2/user/me' #kakao Api 주소
        response         = requests.get(KAKAO_INFO_API, headers={'Authorization': f'Bearer {access_token}'}, timeout=5)
        #kakao Api에 kakao_token을 헤더에 넣어 전송해 해당하는 사용자 정보를 요청한다.

        if not response.status_code == 200:
            return JsonResponse({'message' : 'INVALID_RESPONSE' }, status = 400)
        #요청한 response가 유효하지 않을 경우의 에러처리

위의 코드와 같이 kakao Api와 통신하여 response에 kakao_token에 해당하는
사용자 정보를 저장하였다.

이제 받아온 데이터를 가지고 로그인과 회원가입을 진행해보자.

        user_information = response.json() #reponse를 json형태로 변환
        kakao_id         = user_information['id']
        user_name        = user_information['properties']['nickname']
        email            = user_information['kakao_account']['email']
		#객체에 데이터 저장하기
        is_user = User.objects.filter(kakao_id = kakao_id).exists()
		#중복되는 kakao_pk값이 존재하는지 여부를 저장
        #프로젝트에서 회원가입과 로그인을 분기하기 위한 변수(is_user)
        result = {
            'kakao_id'  : kakao_id,
            'user_name' : user_name,
            'email'     : email,
            'is_user'   : is_user
        }

        return JsonResponse({'result' : result }, status = 200)

kakao Api와 통신하여 가져온 데이터들을 중복 유효성 검사 진행 후 결과와 함께 그대로 반환해 주었다. 사실, 바로 회원가입과 로그인 로직을 구현할 수도 있지만, 이렇게 반환해버린 이유에 대해 설명해 보겠다.


우리 프로젝트에서 소셜회원가입을 시도할 경우, kakao Api에서 받아온 데이터 그대로 회원가입이 진행되는게 아니라, 위와 같은 수정페이지가 추가로 존재한다.
혹시, 데이터를 수정할 경우 FE와의 통신이 추가로 필요하기 때문에, 분리해서 Api를 구현해 보았다.

def post(self, request): 
    try:
        data = json.loads(request.body)

        validate_email(data['email']) #FE로부터 전달받은 email의 유효성 검사

        user, is_created = User.objects.get_or_create(
            kakao_id = data['kakao_id'],
            defaults = {
                'user_name' : data['user_name'],
                'email'     : data['email']
            }
        )
        #get_or_create 메소드를 사용해 중복가입 유효성 검사를 해보았다
        
        status       = 201 if is_created else 200 #가입일 경우 201, 로그인일 경우 200 반환
        message      = 'CREATE_ACCOUNT' if is_created else 'LOGIN_SUCCESS'
        client_token = jwt.encode({'id':user.id}, settings.SECRET_KEY, settings.ALGORITHM) 
        #우리 프로젝트의 token을 발급해야 한다.
        
        return JsonResponse({'message': message, 'token': client_token}, status=status)

    except ValidationError as error:
        return JsonResponse({"message" : error.message}, status = 400)

    except KeyError:
        return JsonResponse({"message" : "KEYERROR"}, status = 400)

FE로부터 수정된 데이터를 전송받을수도 있기 때문에 POST 메소드로 구현하였다.
회원가입과 로그인 기능을 한번에 작동할 수 있게 get_or_create 메소드를 사용해 분기하였다.
새로운 데이터가 생성되었다면(회원가입) status 201, 기존에 데이터가 존재한다면(로그인) status 200을 반환한다.
로그인에 성공했다면 client_token을 발급한다.
모든 로직에 문제가 없었다면, 메세지,토큰,status 코드를 반환한다.

profile
반가워요!

0개의 댓글