TIL DAY 19 || Login Decorator with Response Header

tk_kim·2021년 3월 11일
0

TIL

목록 보기
26/55

Django framework 에서 로그인 이후 token 을 검증하는 로직을 매번 get, post 에 구현하려면 코드가 매우 길어진다.

따라서 jwt 를 검증하는 decorator 를 만들어서 코드의 길이를 줄여보기로 했다.

auth_check Decorator

다음은 auth_check 데코레이터 함수로 둘러쌓여있는 get() 함수이다.

다음은 로그인 auth check 로직이 들어있는 데코레이터 함수이다.

import jwt
import json
from jwt.exceptions import InvalidSignatureError, DecodeError

from django.http import JsonResponse

from account.models             import User
from project_westagram.settings import SECRET_KEY
from utils.debugger             import debugger


def auth_check(func):
    def wrapper(self, request):
        data = request.headers
        try:
            encoded_auth_token = data.get('Authorization')
            decoded_auth_token = jwt.decode(encoded_auth_token, SECRET_KEY, algorithms='HS256')
            
            user_id = decoded_auth_token['user_id']
            user    = User.objects.get(id=user_id)

            request.user = user
            return func(self, request)

        except KeyError:
            return JsonResponse({'message': 'AUTHORIZATION_KEY_ERROR'})
        except InvalidSignatureError:
            return JsonResponse({'message': 'SIGNATURE_VERIFICATION_FAILED'})
        except DecodeError:
            debugger.exception('DecodeError')
            return JsonResponse({'message': 'DECODE_ERROR'})
        except User.DoesNotExist:
            return JsonResponse({'message': 'USER_DOES_NOT_EXIST'})
    return wrapper
  1. 먼저 auth_check 데코레이터에 감싸져 있는 함수를 호출한다.

  2. auth_check 데코레이터 함수가 get() 함수 자체를 인자로 받아 호출된다.

  3. auth_check 함수는 wrapper 함수 자체를 리턴한다.

  4. wrapper 함수 안에서 self 와 request 를 인자로 받는다. *args**kwrags 를 추가하지 않은 이유는 내가 어떤 값을 받을 것인지 이미 알고있기 때문이다. (self 객체와 request object 두개) 하지만 어떤 값이 들어올지 모른다면 추가해주는게 맞다.

  5. request.headers 의 "Authorization" 키값의 value 를 통해 프론트에서 넘겨받은 token 가져온다.

  6. jwt 모듈을 사용하여 장고 프로젝트의 SECRET_KEY 값을 넣고 내 서버가 발급한 token 인지를 검증한다. (값이 안나오면 에러가 난다.)

  7. decoding 된 token 은 payload 의 값을 담고있으며, payload 안에는 내가 서버를 통해 보낸 {'user_id': <user_id>} 값이 담겨있다.

  8. user_id 를 통해 로그인 하는 유저의 User 객체를 가져온다.

  9. request object 에 user 를 추가하고 User 객체를 할당한다.

  10. wrapper 함수에서 func(self, request) 를 리턴한다.
    리턴하기 전에 에러가 나면 데코레이터 함수 선에서 처리가 되기 때문에 따로 View 함수 안에서 구현해줄 필요가 없다.

profile
Backend Developer

0개의 댓글