TIL no.35 Westagram Decorator

백선호·2021년 7월 29일
0

TIL

목록 보기
32/39
post-thumbnail

사용자가 로그인이 성공되었을 경우 사용자는 서버에게 JWT 토큰을 받게 된다. 기본적으로 서버는 무상태 상태인데, 사용자가 로그인을 요구해야 하는 기능을 사용하게 될 때 request의 header에 토큰을 함께 보내주면 서버는 토큰을 읽어줘야 한다. 토큰을 읽을 때 파이썬 데코레이터를 사용하면 간단하게 혜결이 가능하다. 즉 서버 입장에서는 토큰을 읽어 무상태 상태를 혜결한다.

Decorator란?

직역하면 "장식하다"라는 의미로 무엇인가를 장식하는 것이다. 즉 쉽게 말해 본래의 함수가 실행하기 전에 데이 레이터 함수가 먼저 실행한 뒤 본래의 함수가 실행되는 구조이다. westagram 프로젝트에서는 인가를 요구하는 기능에 인가를 확인해 주는 데코레이터를 만들어 먼저 실행하고 그다음 본래의 기능의 함수가 실행한다. 사용하는 방법은 간단하다. decorator 사용하는 함수는 함수의 이름 앞에 @를 붙여서 적용하고자 하는 함수 정의 부분 위에 지정해 주면 된다.

def decorator1(func):
    def wrapper():
        print('decorator1')
        func()
    return wrapper
 
def decorator2(func):
    def wrapper():
        print('decorator2')
        func()
    return wrapper
 

@decorator1
@decorator2
def hello():
    print('hello')
 
hello()

#실행 결과
decorator1
decorator2
hello

상위 간단한 코드를 예를 들어 보겠다. 실행 결과를 보면 hello라는 함수가 실행시켰지만 파이썬은 위에서 아래로 코드가 실행되는 로직을 갖고 있기 때문에 decorator1이 실행되고 decorator2가 실해되고 hello 함수가 실행된다.

westagram 적용

데코레이터를 쉽게 불러오기 위해서 새로운 앱을 생성한뒤 앱 내부에 utils.py파일안에 데코레이터 함수를 작성한다.

#필요한 모듈을 불러온다.
from django.http.response   import JsonResponse
from users.models           import User
from my_settings            import SECRET_KEY
from django.core.exceptions import ObjectDoesNotExist     
import jwt 

필자는 보안을 위해서 SECRET KEY를 새로운 파일을 만들어서 따로 저장해두었기 때문에 임포트해주었다.

def token_reader(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            token        = request.headers.get('Authorization', None)
            payload      = jwt.decode(token, SECRET_KEY, algorithms='HS256')
            user         = User.objects.get(id=payload['id'])
            request.user = user
        
        except jwt.exceptions.DecodeError:
            return JsonResponse({'message' : 'INVALID_TOKEN' }, status=400)

        except User.DoesNotExist:
            return JsonResponse({'message' : 'INVALID_USER'}, status=400)

        return func(self, request, *args, **kwargs)

    return wrapper
    
  1. token은 HTTP request의 header에서 값을 보내기 때문에 우리는 header에서 읽어오는데, .get() d을 사용하여 Authorization의 값이 있으면 가져오고, 값이 없다면 None을 넘긴다.
  2. payload에는 디코딩을 하면 나오게 될 사용자에 정보를 담을 건데 이때 SECRET KEY와 algorithms에 대한 정보는 encode 한 정보와 동일해야 한다. 꼭 algorithms로 입력해야 한다.
  3. 디코딩 해서 나온 사용자에 대한 정보와 매칭되는 사용자 정보를 불러오고, user라는 변수에 저장한다.
  4. request.user는 user를 할당해서 본래의 함수 내부에서 사용할 수 있게 변수로 할당했다.
  5. DecodeError는 토큰 값이 없을 경우 예외 처리한다.
  6. 존재하지 않는 사용자일 때 예외 처리를 한다.
profile
baik9261@gmail.com

0개의 댓글