Applion 002|django KACA登録実施

29108 ワード

  • の通常登録/会員登録を含むKACA登録も
  • を追加し、ユーザーの使用を便利にした
    
    def kakao_login(request):
        """
        
        """
        if request.user.is_authenticated:
            return redirect("user_info")
        rest_api_key = settings.KAKAO_REST_API_KEY
        redirect_uri = "http://www.applionsg.com/user/kakao/login/callback/"
        state = "none"
        return redirect(
            f"https://kauth.kakao.com/oauth/authorize?client_id={rest_api_key}&redirect_uri={redirect_uri}&response_type=code&state={state}"
        )
    
    
    def submit_kakao(request):
        """
        카카오/일반 회원가입 후 추가 정보 받고 유저에 저장하는 뷰입니다
        처음엔 카카오만 그 대상이었어서 ㅠㅠ 이름 헷갈리게 지은 점 죄송합니다
        """
        if not request.user.is_authenticated:
            return redirect("email_login")
        form = Emailform(request.POST, instance=request.user)
        if request.method == "POST":
            form = Emailform(request.POST, instance=request.user)
            if form.is_valid():
                form.save()
                return redirect("user_info")
        return render(request, "signup_info.html", {"form": form})
    
    
    def kakao_login_callback(request):
        """
        1) 인가코드 받기 -> redirect uri 인가 코드가 리다이렉트될 URI
        2) access_token 받기 -> 카카오 서버상 로그인 완료
        3-1) 카카오 첫 로그인일 경우 회원가입/로그인 진행 
        => 카카오로부터 사용자 정보 받기 (name (필수), email(옵션))
        => 추가 정보 받을 HTML로 이동시키기 (이메일, 학번, 전공, 전화번호)
        3-2) 카카오 로그인 했던 사람인 경우, 바로 로그인 진행
        4) 회원가입/로그인 완료 후 이동할 HTML로 넘어가기
        """
        code = request.GET.get("code")
        if code is None:
            raise Exception("code is none")
    
        state = request.GET.get("state")
        token_url = "https://kauth.kakao.com/oauth/token"
        rest_api_key = settings.KAKAO_REST_API_KEY
        redirect_uri = "http://www.applionsg.com/user/kakao/login/callback/"
        res = requests.post(
            token_url,
            data={
                "grant_type": "authorization_code",
                "client_id": rest_api_key,
                "redirect_uri": redirect_uri,
                "code": code,
            },
        )
        token_response = res.json()
        access_token = token_response.get("access_token")
        info_url = "https://kapi.kakao.com/v2/user/me"
        headers = {"Authorization": f"Bearer {access_token}"}
        params = {"secure_resource": True}
        info_res = requests.get(info_url, headers=headers, params=params)
    
        try:
            info = info_res.json()
        except:
            info = None
        kakao_id = str(info.get("id"))
    
        try:
            test = CustomUser.objects.get(kakao_id=kakao_id)
        except CustomUser.DoesNotExist:
            test = None
    
        if test is None:
            personal_info = info.get("kakao_account")
            agree_on_nickname = personal_info.get("profile_needs_agreement")
            if not agree_on_nickname:
                profile = personal_info.get("profile")
                name = profile.get("nickname")
            agree_on_email = personal_info.get("email_needs_agreement")
    
            if not agree_on_email:
    
                email = personal_info.get("email")
    
                if len(CustomUser.objects.filter(email=email)) != 0:
                    form = EmailAuthenticationForm(request.POST)
                    msg = "already_signedup"
                    return render(
                        request,
                        "email_login.html",
                        {"form": form, "already_signedup": msg},
                    )
    
            else:
                form = UserSignupForm
                return render(
                    request,
                    "signup_email.html",
                    {"form": form, "error_code": "kakao_error"},
                )
            user = CustomUser.objects.create_user(
                email,
                None,
                True,
                name,
                kakao_id,
                "major",
                "phone_number",
                "student_id",
                "position",
            )
            form = (
                Emailform()
            )  # email, password, is_kakao, name, kakao_id , major, phone_number, student_id
            login(
                request, user, backend="user.kakaobackends.KakaoBackend"
            )  # 카카오 이메일을 안받는다면
            return render(request, "signup_info.html", {"form": form})
    
        else:
            login(
                request,
                CustomUser.objects.get(kakao_id=kakao_id),
                backend="user.kakaobackends.KakaoBackend",
            )
            if state == "none":
                return redirect("user_info")  # TO-DO : 우선은 로그인 완료 후 임시 페이지로 이동하게 함
            else:
                return redirect("user_info")
    
    
    def logout_view(request):
        """
        로그아웃 처리
        1) 카카오로그인 경우 - 이 서비스에서만 로그아웃
        2) 일반 로그인 경우
        => 로그아웃 완료 후 우선은 login_home으로 돌아가게 해놓음, 상의 필요
        """
        if request.user.is_kakao:
            kakao_admin_key = settings.KAKAO_ADNIN_KEY
            logout_url = "https://kapi.kakao.com/v1/user/logout"
            target_id = request.user.kakao_id
            target_id = int(target_id)
            headers = {"Authorization": f"KakaoAK {kakao_admin_key}"}
            data = {"target_id_type": "user_id", "target_id": target_id}
            logout_res = requests.post(
                logout_url, headers=headers, data=data
            ).json()
            response = logout_res.get("id")
            if target_id != response:
                return Exception("Kakao Logout failed")
            else:
                print(str(response) + "Kakao Logout successed")
        logout(request)
        return redirect("index")
    
    
    def logout_with_kakao(request):
        """
        카카오톡과 함께 로그아웃 처리
        """
        kakao_rest_api_key = settings.KAKAO_REST_API_KEY
        logout_redirect_uri = "http://www.applionsg.com/user/logout/"
        state = "none"
        kakao_service_logout_url = "https://kauth.kakao.com/oauth/logout"
        return redirect(
            f"{kakao_service_logout_url}?client_id={kakao_rest_api_key}&logout_redirect_uri={logout_redirect_uri}&state={state}"
        )
    
    
    def delete_user(request, user_pk):
        """
        탈퇴하기
        """
        user = request.user
        if user.pk == user_pk:
            if user.is_kakao:
                kakao_admin_key = settings.KAKAO_ADNIN_KEY
                user_kakao_id = int(user.kakao_id)
                url = "https://kapi.kakao.com/v1/user/unlink"
                headers = {"Authorization": f"KakaoAK {kakao_admin_key}"}
                data = {"target_id_type": "user_id", "target_id": user_kakao_id}
                res = requests.post(url, headers=headers, data=data)
                deleted_user_id = res.json().get("id")
                if deleted_user_id == user_kakao_id:
                    print("연결 끊기 성공")
                else:
                    print("연결끊기 실패")
            logout(request)
            user.delete()
            return redirect("login_home")
        else:
            raise ValidationError("잘못된 접근입니다.")