import jwt
from django.http.response import JsonResponse
from .models import User
import my_settings
def login_required(func):
def decorator(self, request, *args, **kwargs):
try:
access_token = request.headers['Authorization']
decoded_token = jwt.decode(access_token, my_settings.SECRET['secret'], algorithms='HS256')
user = User.objects.get(id=decoded_token['user_id'])
request.user = user
return func(self, request)
except User.DoesNotExist:
return JsonResponse({'message':'UNKNOWN_USER'}, status=400)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
except jwt.DecodeError:
return JsonResponse({'message':'INVALID_TOKEN'}, status=400)
return decorator
지금껏 로그인 데코레이터를 만들었지만, 개별 코드의 의미를 정확히 이해하고 만든 것은 아니었다. 이번에는 코드를 한 줄씩 따져가며 데코레이터를 짜봤는데, 몇 가지 놓치고 있던 점을 발견하여 정리해보려 한다.
decorator 함수의 매개변수에는 self와 request가 모두 입력돼야 한다.
decorator 함수가 Class 내부에 정의되지 않기 때문에, self
를 입력할 필요 없다고 생각했다. 하지만 self
를 입력하지 않고 첫 번째 매개변수로 request
를 입력하는 경우, request 인자값이 제대로 받을 수 없게 된다.
더군다나, 인자로 받은 함수를 실행시키는 코드인 return func(self, request)
의 매개변수 self의 값이 def decorator(self, request, *args, **kwargs):
의 매개변수 self값에 의해 정의되기 때문에, 'self'를 매개변수로 지정하지 않으면 인자로 받은 함수 실행도 할 수 없게 된다. 결론을 말하자면, 정확한 이유를 알 수 없지만... , 데코레이터 모듈에서 self인자는 반드시 필요하다.
jwt.DecodeError vs json.JSONDecodeError
Except jwt.DecodeError:
: jwt 모듈로 생성한 token을 decode할 때 발생할 수 있는 Error를 예외처리를 할 때 사용한다.
Except json.DecodeError:
: HTTP요청의 body에 포함된 json 데이터를 읽는 과정에서 발생하는 Error를 예외처리할 때 쓴다.