- 일반로그인/회원가입을 비롯한 카카오 로그인도 사용자 편의를 위해 추가했습니다.
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()
)
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")
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("잘못된 접근입니다.")