아 방금 겁나 자세하게 글 썼는데 다 날라감...짜증...
임시저장 했는데 왜 날라갔니 벨로그야???
하여간 카카오 로그인을 할때 나는 기업이 아니라 email인증이 필수가 안된다.
만약 유저가 체크를 안하면 email을 받아오지 못하기 때문에 그럴때 따로 이메일을 받아오는 페이지를 만들어서 이메일을 받기로 했다.
코드def kakao_social_login_callback(request):
"""
받은 인가 코드, 애플리케이션 정보를 담아 /oath/token/에 post요청하여 접근코드를 받아 처리하는 함수
"""
try:
code = request.GET.get('code')
client_id = my_settings.KAKAO_CLIENT_ID # 앱 키
redirect_uri = 'http://127.0.0.1:8000/account/login/kakao/callback' # 인가 코드를 받은 URI
token_request = requests.post(
'https://kauth.kakao.com/oauth/token', {'grant_type': 'authorization_code',
'client_id': client_id, 'redierect_uri': redirect_uri, 'code': code}
)
token_json = token_request.json()
#------------유효성 검증 --------------#
error = token_json.get('error', None)
if error is not None:
print(error)
return JsonResponse({"message": "INVALID_CODE"}, status=400)
#-------------받은 토큰---------------#
access_token = token_json.get("access_token")
except KeyError:
return JsonResponse({"message": "INVALID_TOKEN"}, status=400)
except access_token.DoesNotExist:
return JsonResponse({"message": "INVALID_TOKEN"}, status=400)
#------토큰을 이용하여 사용자 정보 조회------#
profile_request = requests.get(
"https://kapi.kakao.com/v2/user/me", headers={"Authorization": f"Bearer {access_token}"},
)
#------사용자 정보를 활용---------------#
profile_json = profile_request.json()
print(profile_json)
#nickname 만들어 주는 함수
def make_nickname():
_LENGTH = 8 #8자리
string_pool = string.ascii_lowercase #소문자
result = ''
for _ in range(_LENGTH):
result += random.choice(string_pool)
return result
kakao_id = profile_json.get('id')
username = profile_json['properties']['nickname']
if User.objects.filter(kakao_id = kakao_id).exists():
user = User.objects.get(username = username)
auth.login(request,user,backend='django.contrib.auth.backends.ModelBackend')
return redirect('/')
try:
email = profile_json['kakao_account']['email']
except:
context = {
'nickname' : make_nickname(),
'username' : username,
'kakao_id' : kakao_id,
}
return render(request,'user/kakao_email.html', context)
if User.objects.filter(nickname = nickname).exists():
nickname = make_nickname()
else:
User.objects.create_user(
username =username,
nickname = nickname,
email = email
)
user = User.objects.get(username = username)
auth.login(request,user,backend='django.contrib.auth.backends.ModelBackend')
#error
#You have multiple authentication backends configured and therefore must provide the `backend` argument or set the `backend` attribute on the user.
return redirect('/')를 입력하세요
여기서
코드를try:
email = profile_json['kakao_account']['email']
except:
context = {
'nickname' : make_nickname(),
'username' : username,
'kakao_id' : kakao_id,
}
return render(request,'user/kakao_email.html', context)
이렇게 email정보가 없으면 다른 받아온 정보를 들고 이메일 입력 페이지로 넘어가게 했는데
def kakao_email(request, kakao_id, username, nickname):
if request.method == 'GET':
return redirect('user:kakao_email')
elif request.method=='POST':
username =username
kakao_id = kakao_id
nickname = nickname
email = request.POST.get('email')
print(username, kakao_id, nickname, email)
exist_user = get_user_model().objects.filter(email=email)
if not exist_user:
User.objects.create_user(
username = username,
email = email,
kakao_id = kakao_id,
nickname = nickname,
)
return render(request, 'user/login.html')
else:
return JsonResponse({"message": "이미 존재하는 계정입니다."}, status=400)
이메일만 input으로 받고 싶어서 url에 카카오 아이디, 유저네임, 닉네임 다 주렁주렁달고 값을 받아오게 했더니 if문 가입까지는 되었는데 else문
이미 가입된 유저가 있을때 render로 페이지를 넘기면 저 지저분한 url들이 다같이 넘어가서 에러가 생겼다.
redirect를 사용하면 원하는 페이지를 갈 수 있지만 그러면 error메시지를 전달해 주지 못하기 때문에 ...
걍 html에 input태그들을 여러개 만들어서 이미 받아온 값들은 input value에 넣어서 email만 넣게 할까도 고민했지만 email input만 보여지고 싶어서...
아무래도 kakao_id 고유값으로 email을 넣어줘서 일단 가입 시킨다음에
email 수정 창으로 유도를 해야하는 방법을 써야할 것 같다.
곧...
두번째 곤욕.
def kakao_social_login_callback(request):
이 함수에서 이미 가입을 했는데도
try:
email = profile_json['kakao_account']['email']
except:
context = {
'nickname' : make_nickname(),
'username' : username,
'kakao_id' : kakao_id,
}
return render(request,'user/kakao_email.html', context)
카카오에서 넘어온 정보가 아니기 때문에 계속 except에 걸려서 계속 이메일을 만드는 페이지로 넘어가게 되었다...
이걸로 엄청 고민하고 여러 시도를 했는데 ㅉ....ㅏ..증
개 쉬운게 문제였다.
으.. 문제해결능력..어디갔니?
try 문을 사용하기 직전에
if User.objects.filter(kakao_id = kakao_id).exists():
user = User.objects.get(username = username)
auth.login(request,user,backend='django.contrib.auth.backends.ModelBackend')
return redirect('/')
이렇게 if 조건문을 넣으면 되는거였다...
ㅋㅋㅋㅋ
그래 뭐..
문제해결능력 언젠간..생기겠지..
하여간 곧 다시 카카오 이메일 부분은 수정할 예정. 끝