TIL 33. 로그인 데코레이터(login decorator)

윤현묵·2021년 9월 5일
0

Django

목록 보기
9/17
post-thumbnail

웹페이지에서 로그인 정보를 유지하기 위해 사용되는 데코레이터에 대해 알아보겠습니다.

먼저 데코레이터에 대해 간단히 설명하자면,
대상 함수를 wrapping하고 이 함수 앞뒤로 꾸며질 구문들에 대해 손쉽게 재사용할 수 있도록 다른 곳에 미리 함수를 만들어 둔 것이라고 볼 수 있습니다. 예로 들자면, 회원이 제품 구매를 위해 장바구니에 상품을 담는 특정권한을 가지고 있는지 확인하기 위해 데코레이터를 구현할 수 있습니다.

ex)사용예시
@decorator
def cart():
~~~~~

개발순서는 회원가입과 로그인을 먼저 구현하고, 데코레이터를 구현해야 하는데 목적과 로직은 아래와 같습니다.

구현하고자 하는 데코레이터의 목적
웹사이트 상에서 권한(로그인, 혹은 관리자)을 가진 유저만 이용가능한 서비스를 이용할 수 곳에 한해서, 유저가 로그인한 유저인지, 이용가능한 권한을 가진 유저인지(게시판 글쓰기, 관리자페이지 이용권한, 포스팅 작성, 장바구니 접속 등) 등을 확인하기 위해서 미리 선언해 둔 함수를 사용하기 위한 목적

로직

  • 유저로그인: 프론트엔드에게 해당 아이디로 발행한 암호화된 jwt토큰을 전달
  • 해당유저의 정보를 확인하기 위해 프론트엔드에서 HTTP 헤더를 통해 토큰을 전달 받기
    → 만약 토큰이 없다면 서버에서는 에러코드를 프론트엔드에게 전달하고, 유저의 현재 페이지를 로그인페이지로 이동해달라고 프론트엔드에게 요청
  • 백엔드는 암호화되어 전달받은 jwt토큰을 decode
    → decode에서 오류가 난다면, 해당 웹페이지에서 발행한 토큰이 아니므로, INVALID_TOKEN 에러를 프론트엔드에게 전달
  • Django models.py에 저장된 데이터와 decode한 데이터가 일치하는 회원의 정보를 변수에 저장
    → 유저의 정보가 없다면, UNKNOWN_USER라는 에러메세지를 프론트엔드에게 전달
  • request할 객체에 user변수를 저장하여 프론트엔드에게 전달
import jwt, json, requests

from django.http import JsonResponse
from django.core.exceptions import ObjectDoesNotExist

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

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            access_token = request.headers.get('Authorization', None)
            print('token', access_token)
            payload = jwt.decode(access_token, SECRET_KEY, algorithms=ALGORITHM)
            print('payload', payload)
            request.user = User.objects.get(id=payload['id'])

        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

코드 설명

  • 데코레이터 구현 및 해당 유저 정보 확인 → 받은 데이터 중에 토큰이 있는지 확인 → 권한이 없을 때 400 에러 발생
  • jwt토큰 decode
    → 받은 토큰과 기존에 저장해두었던 SECRET_KEY와 algorithm으로 토큰을 decode를 하게 될 경우 프론트엔드에 전달했던 payload값만 나옴(즉 로그인 view의 body)
    decode한 토큰과 일치하는 유저 정보를 변수에 저장 → Query문을 이용해 DB에 접근하여 원하는 데이터를 가져온다 → get메소드를 사용할 경우 DB에서 하나의 row만 가지고 옴
    → 유저의 권한이 필요한 부분에 데코레이터를 사용하여 유저정보를 가져와서 활용
profile
진정성 있는 개발자를 꿈꾼다

0개의 댓글