Kakao Developers 에 자세한 구현 방법 확인할 수 있음!
이 문서를 토대로 작성한 코드
@api_view(['GET'])
@permission_classes([AllowAny])
def oauth(request):
code = request.GET['code']
print('code = ' + str(code))
secret_file = os.path.join(BASE_DIR, 'secrets.json')
with open(secret_file) as f:
secrets = json.loads(f.read())
def get_secret(setting, secrets=secrets):
try:
return secrets[setting]
except KeyError:
error_msg = "Set the {} environment variable".format(setting)
raise ImproperlyConfigured(error_msg)
KAKAO_CLIENT_ID = get_secret("KAKAO_CLIENT_ID") # secrets.json에서 ID, Secret Key 받아옴
#KAKAO_CLIENT_SECRET = get_secret("KAKAO_CLIENT_SECRET")
redirect_uri = 'http://127.0.0.1:8000/user/login/kakao/callback'
# request로 받은 code로 access_token 받아오기
access_token_request_uri = 'https://kauth.kakao.com/oauth/token?grant_type=authorization_code&'
access_token_request_uri += 'client_id=' + KAKAO_CLIENT_ID
access_token_request_uri += '&code=' + code
access_token_request_uri += '&redirect_uri=' + redirect_uri
access_token_request_uri_data = requests.get(access_token_request_uri)
json_data = access_token_request_uri_data.json() # json 형태로 데이터 저장
access_token = json_data['access_token'] # 액세스 토큰 꺼내와서 저장
# 프로필 정보 받아오기
headers = ({'Authorization' : f"Bearer {access_token}"}) # header에 꼭 설정해야 함
user_profile_info_uri = 'https://kapi.kakao.com/v2/user/me'
user_profile_info = requests.get(user_profile_info_uri, headers=headers)
json_data = user_profile_info.json()
# 닉네임과 이메일 데이터 가져옴
nickname = json_data['kakao_account']['profile']['nickname']
email = json_data['kakao_account']['email']
# 데이터베이스에 이미 저장되어있는 회원이면, user에 회원 저장
if User.objects.filter(email=email).exists():
user = User.objects.get(email=email)
# 회원가입인 경우
else:
user = User.objects.create(
email=email,
nickname=nickname
)
user.save()
# 토큰 발행
payload = JWT_PAYLOAD_HANDLER(user)
jwt_token = JWT_ENCODE_HANDLER(payload)
response = {
'success' : True,
'token' : jwt_token
}
return Response(response, status=200)
kakao login 시, 기존에 있는 email이면 로그인하고 없으면 회원가입 시킨 후, 로그인을 하게 된다.
이때 기존에 있는 회원인지 조건을 체크할 때 생긴 에러이다
처음에
user = User.objects.get(email=email)
이렇게 작성했다가 DoesNotExist라는 예외가 발생했다.
값이 없을 때 예외를 던지는 것이다
그래서 filter() 메서드의 exists() 로 조건을 체크했다
처음엔
user = User.objects.filter(email=email)
if user.exists():
pass
else:
user = User.objects.create(
email=email,
nickname=nickname
)
user.save()
payload = JWT_PAYLOAD_HANDLER(user)
jwt_token = JWT_ENCODE_HANDLER(payload)
filter를 통해 user을 저장하고, login되어있으면 pass 후, jwt_token을 생성하려고 했는데
payload = JWT_PAYLOAD_HANDLER(user
이 코드에서,
AttributeError: 'QuerySet' object has no attribute 'username'
이런 에러가 발생했다. 그래서 filter로 조건 체크하고, get()으로 user를 저장했다
if User.objects.filter(email=email).exists():
user = User.objects.get(email=email)
print('login')
else:
user = User.objects.create(
email=email,
nickname=nickname
)
user.save()
payload = JWT_PAYLOAD_HANDLER(user)
jwt_token = JWT_ENCODE_HANDLER(payload)
이렇게 하면 성공적으로 로그인하고, 토큰도 발행 성공 !!
Response 를 리턴할 때 @api_view(함수형 뷰) 어노테이션을 써야한다
없다면
AssertionError: .accepted_renderer not set on Response
이 에러 발생
{
"SECRET_KEY" : "~~",
"KAKAO_CLIENT_ID" : "~~",
"KAKAO_CLIENT_SECRET" : "~~"
}
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
secret_file = os.path.join(BASE_DIR, 'secrets.json')
with open(secret_file) as f:
secrets = json.loads(f.read())
def get_secret(setting, secrets=secrets):
try:
return secrets[setting]
except KeyError:
error_msg = "Set the {} environment variable".format(setting)
raise ImproperlyConfigured(error_msg)
SECRET_KEY = get_secret("SECRET_KEY")