카카오 API1 - 카카오 로그인

Yeseul Han·2022년 8월 16일
0
post-thumbnail

시작

플젝을 진행하면서 종종 다른 팀들이 카카오 로그인을 시도하는것을 보았고 카카오 로그인을 꼭 한 번 해보고 싶다는 마음을 키우게 되었다.

실제로 해보니 어렵지 않았다. 그래도 자바스크립트로 구현되는 코드인 만큼 자바스크립트가 익숙하지 않은 시점에 시도했다면 꽤 난감했겠다 싶었다.

어떻게?

역시 난 영상 컨텐츠가 최고다. 이 튜토리얼 영상을 많이 참고 했다.

1. 어플리케이션 추가하기

먼저 카카오 디벨로퍼 사이트에 들어가 로그인을 하고 어플리케이션을 추가한다.

내 사이트 명이 petrasche 였기에 앱 이름과 사업자명을 petrasche로 지정하고 저장 버튼을 눌렀다.

2. javascript키 확인

만들어진 어플리케이션을 클릭하면 바로 요약정보 페이지로 가는데
여기서 javascript 앱 키를 확인하는 것이 중요하다. 이 키는 앞으로 내가 쓴 코드라는걸 확인시켜줄 것이다.

3. 플랫폼 URI 등록 & redirect URI등록

다음엔 플랫폼 탭으로 넘어가서 플랫폼 URI를 등록한다.
지금 배포가 마무리된 상태라 실제 도메인이 다 쓰여 있는데, 개발중일때는 프론트에 해당하는 http://127.0.0.1:5500 이나 http://localhost:5500을 uri에 넣어주면 된다.

이번엔 플랫폼 탭 밑에 있는 redirect uri '등록하러 가기'를 클릭해보자.
여기에 있는 redirect uri는 로그인을 시도할 프론트 uri를 넣어줘야한다. 예를 들어 http://127.0.0.1:5500/login.html 이런 식으로!

4. 동의항목 추가

동의항목으로 넘어가보자. 여기서 동의항목이란 로그인시 카카오에서 우리 사이트로 넘겨올 정보를 말한다. 내가 필요한 정보를 클릭해서 설정을 바꿔주면 되는 간단한 작업. 난 이메일과 성별을 이용중 동의로 설정했다.

5. 프론트엔드 코드

Kakao.init("요 따옴표 사이에 자바스크립트 키를 넣어주면 된다")

function kakaoLogin() {
    window.Kakao.Auth.login({
        scope: 'profile_nickname, account_email, gender', 
      //scope에는 불러올 동의항목의 이름들이 들어간다.
        success: function (authoObj) {
            window.Kakao.API.request({
                url: '/v2/user/me',
                success: res => {
                    const kakao_account = res.kakao_account;
                    const signupData = {
                        email: kakao_account.email,
                        username: kakao_account.profile.nickname
                    }
                    //여기까지 잘하면 handleKakaoSignup 함수로 넘어간다
                    handleKakaoSignup(authoObj, signupData)
                }
            });
        },
        fail: function (error) {
            console.log(error);
        }
    });
function handleKakaoSignup(authoObj, signupData) {//signup
    const kakaoSignupData = Object.assign({}, authoObj, signupData);
    const response = fetch(`${backend_base_url}user/kakao/`, {
        headers: {
            Accept: 'application/json',
            'Content-type': 'application/json'
        },
        method: 'POST',
        body: JSON.stringify(kakaoSignupData)
    })
        .then((res) => {
            if (res.status === 200) {
                res.json().then((res) => {
                    localStorage.setItem("user_access_token", res.access);
                    localStorage.setItem("user_refresh_token", res.refresh);
                    // window.location.replace("http://127.0.0.1:5500/index.html");
                    const base64Url = res.access.split('.')[1];
                    const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
                    const jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
                        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
                    }).join(''));
                    localStorage.setItem("payload", jsonPayload)
                    window.location.replace(`/index.html`)
                })
            } else if (res.status === 201) {
                alert("회원가입에 성공하셨습니다. 로그인을 해주세요.");
                window.location.replace(`${frontend_base_url}login.html`);
            } else if (res.status === 400) {
                res.json().then((res) => {
                    alert(res.error)
                    window.location.replace(`${frontend_base_url}signup.html`);
                })
            }
        })
}

5. 백엔드 코드 user/views.py

여기서 핵심은 로그인과 회원가입이 같은 함수를 탄다는 것이다.

기존에 가입된 유저가 있는지 여부를 try except문을 사용해서 분기를 나눴고, 기존에 가입된 유저가 없으면 회원가입 아니면 로그인을 진행했다.

회원 가입시에는 유저 모델에 저장한 뒤에 그 정보를 사용해 유저 프로필 모델에도 저장하도록 했다. 속도는 충분히 빨랐다.

class KakaoLoginView(APIView):
    permission_classes = [permissions.AllowAny]
    def post(self, request):
        email = request.data['email']
        username = request.data['username']
        try: 
            # 기존에 가입된 유저가 있다면 로그인
            user = User.objects.get(email=email)
            if user and (user.password==None):
                refresh = RefreshToken.for_user(user)

                return Response({'refresh': str(refresh), 'access': str(refresh.access_token), "msg" : "로그인 성공"}, status=status.HTTP_200_OK)
            elif user and (user.password!=None):
                return Response({"error": "해당 카카오 이메일을 사용해 일반 회원가입한 회원입니다"}, status=status.HTTP_400_BAD_REQUEST)
        except User.DoesNotExist:
        # 기존에 가입된 유저가 없으면 새로 가입           
            new_user = User.objects.create(
                username=username,
                email=email,
            )
            new_user.save()
            user = User.objects.get(username=username)
            new_user_profile = UserProfile.objects.create(user=user)
            new_user_profile.save()
            return Response({"msg": "회원가입에 성공 했습니다."}, status=status.HTTP_201_CREATED)
profile
코딩 잘하고 싶다

0개의 댓글