[Mission 6] 로그인 JWT 발급
1. 로그인 로직 변경
import json, bcrypt, jwt
from django.http import JsonResponse
from django.views import View
from users.validation import validate_email, validate_password
from users.models import User
from my_settings import SECRET_KEY, ALGORITHM
class LoginView(View):
def post(self, request):
data = json.loads(request.body)
try:
email = data['email']
password = data['password']
if not User.objects.filter(email = email).exists():
return JsonResponse({'message' : 'INVALID_USER'},status=401)
user = User.objects.get(email = email)
hashed_password = user.password.encode('utf-8')
if bcrypt.checkpw(password.encode('utf-8'), hashed_password):
access_token = jwt.encode({'id':user.id}, SECRET_KEY, ALGORITHM)
return JsonResponse({'message':'SUCCESS', 'access_token':access_token}, status=200)
return JsonResponse({'message' : 'INCORRECT_PASSWORD'},status=401)
except KeyError:
return JsonResponse({'message' : 'KEY_ERROR'},status=400)
if bcrypt.checkpw(password.encode('utf-8'), hashed_password):
access_token = jwt.encode({'id':user.id}, SECRET_KEY, ALGORITHM)
bcrypt.checkpw
: boolean 타입으로 비밀번호화 암호화된 비밀번호를 인자로 받아 같을 경우 true, 다를 경우 false를 반환한다.
(password.encode('utf-8'), hashed_password)
: bcrypt는 bytes형식을 인자로 받으므로 받은 패스워드를 bytes로 인코딩합니다.
jwt.encode({'id':user.id}, SECRET_KEY, ALGORITHM)
: payload에 로그인 한 user의 id를 담아서 secret key와 함께 선택한 algorithm으로 암호화한다.
PyJWT
를 최신버전으로 설치했다면 access_token을 decode하지 않아도 문자열 형태로 출력하고 저장할 수 있습니다.
2. JWT 발급
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mjd9.63tzKLW7thTIWEsFJKmpTpnqRyHYJTTUHSCrG3tQ1rQ"
- header : 토큰의 타입과 해시 암호화 알고리즘
- payload : 토큰에 담을 클레임(claim) 정보
- signature : secret key를 암호화
4. 발생했던 오류들
- login을 westagram 가상환경에서 http로 요청을 보냈는데 자꾸만
TypeError: Object of type bytes is not JSON serializable
이라는 에러가 발생했다. 알고보니 서버를 돌리는 터미널에서 base가상환경으로 돌리고 있었는데 이 가상환경의 PyJWT버전이 2.0이하라서 access_token을 문자열형식으로 변환하지 못하고 bytes형식으로 남겨두어서 발생한 오류였다. PyJWT버전이 2.0이상인 westagram가상환경에서 서버를 돌리자 정상적으로 작동했습니다.