효율적으로 코드 짜기! 작동만 된다고 끝이 아니다!
어떤 역할을 수행하는 함수가 상당히 많을 때, 그 모든 함수에 동일한 기능을 추가하는 것은 비효율적이다.
반복적이고 부가적인 기능을 데코레이터로 만들어놓고, 필요할 때마다 불러오면 효율적으로 코드를 짤 수 있다.
데코레이터의 본질은 클로저! 이다. 함수를 다른 함수의 인자로 전달한다는 것이 데코레이터의 특별한 점이다.
클로저란?
함수를 둘러싼 환경(지역 변수, 코드 등)을 계속 기억하다가, 함수를 호출할 때 다시 꺼내서 사용하는 기법을 클로저(closure)라고 한다. 클로저는 외부함수에 어떤 변화(심지어는 삭제)가 발생되어도 자신의 스코프는 지킨다.
데코레이터는 기본적으로 함수 위에서 함수가 실행 되기 전에 먼저 동작한다.
고객이 로그인을 하고 다른 곳으로 이동하려고 하기전에 그 곳으로 이동할수 있는 권한. 즉 token이 있는지 확인하는 역할을 데코레이터가 한다고 보면 된다. 만약 token이 유효하지 않으면 이후 동작은 실행되지 않는다.
import jwt
from django.http import JsonResponse
from sulsajo.settings import ALGORITHM, SECRET_KEY
from users.models import User
def log_in_decorator(func):
def wrapper(self, request, *args, **kwargs):
try:
access_token = request.headers.get('Authorization')
payload = jwt.decode(access_token, SECRET_KEY, algorithms=ALGORITHM)
request.user = User.objects.get(id=payload['id'])
return func(self, request, *args, **kwargs)
except User.DoesNotExist:
return JsonResponse({'message' : 'invalid_user'}, status=401)
except jwt.InvalidSignatureError:
return JsonResponse({'message' : 'invalid_signature'}, status=401)
except jwt.DecodeError:
return JsonResponse({'message' : 'invalid_payload'}, status=401)
return wrapper