[Westagram] -6

김가람휘·2022년 2월 23일
0

Westagram

목록 보기
6/9

[Mission 6] 로그인 JWT 발급

1. 로그인 로직 변경

# users/view.py
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
# my_settings에서 환경변수 생성 (.gitignore)
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)
            # 여기서는 checkpw를 이용하여 패스워드를 비교해야하므로 decode해주지 않는다.
            hashed_password = user.password.encode('utf-8')
			
            # 로그인 성공시 JWT(JSON Web Token) 생성
            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가상환경에서 서버를 돌리자 정상적으로 작동했습니다.

0개의 댓글