Decorator


🚀 Decorator
独立したHTTP通信なので、ページをめくるたびに新しい認証が行われます.
新しいページで認証する必要がありますが、認証コードがすべてのコードに貼られるたびに、コードが複雑で冗長になります.
コードの可読性と簡潔性のためには、認証を実施した後にDecoratorを使用することが望ましい.
import jwt

from django.http.response import JsonResponse

from my_settings  import SECRET_KEY, ALGORITHM
from users.models import User

def login_required(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            access_token = request.headers.get('Authorization', None)
            # 프론트가 http요청에서 헤더에 Authorization:key값, access_token:value값 백에게 보냄! 
            # 데코레이터함수는 authorization 값을 읽고, 토큰이 맞는지 확인
            # 토큰이 맞으면(있으면), 그값을 복호화(decoding)해서 사용자 id 읽어들이고 해당 사용자의 로긴 여부 확인   

            payload = jwt.decode(access_token, SECRET_KEY, algorithms=ALGORITHM)
            # 토큰을 디코딩해서 나오게 될 사용자에 대한 정보를 payload에 담는다.
            # 동일한 사용자라면 발행할 때 나온 토큰하고 동일한 토큰이 payload에 반환되겠지
            # 디코딩시 secret_key와 algorithm은 토큰 발행시 넣었던 정보와 같아야함!

            user = User.objects.get(id=payload['user_id']
            # 토큰 디코딩해서 얻은 사용자 정보와 매칭되는 사용자 정보를 user 변수에 저장!

            request.user = user
            # request객체에 user객체 넣어주기. (request객체 has headers, body, startline)
            # request객체에 추가된 user객체는 그대로 데코레이터를 빠져나오는 순간 사라지지않고 views.py에 있는 Profile클래스의 get매서드에 전해진다.

        except jwt.DecodeError:
            # 없는 토큰값 들어오면 DecodeError 처리!

            return JsonResponse({"message":"invalid_token"}, status=401)

        except User.DoesNotExist:
            # 잘못된 유저가 들어오면 DoesNotExist 처리!

            return JsonResponse({"message":"Unknown_user"}, status=400)
        return func(self, request, *args, **kwargs)
    return wrapper
    # 조건이 모두 맞아 떨어지면 시작될 때 받은 parameter를 전부 다 리턴,
    # 마지막으로 wrapper함수 리턴