[TIL / Django] Westagram 5 - 토큰 인증 (utils.py작성)

나른한 개발자·2022년 1월 23일
0

studylog

목록 보기
33/45

지난 시간에는 로그인을 성공했을 시 토큰을 발급하는 것을 구현했다.

이번에는 users앱 내에 utils.py를 작성하여 로그인 토큰이 유효한지 검사하는 것을 구현해 볼 것이다.

from jwt

from django.http import JsonResponse
from django.conf import settings

from users.models import User

def token_auth(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            access_token = request.headers.get("Authorization", None)
            payload = jwt.decode(acces_token, settings.SECRET_KEY, settings.ALGORITHM)
            user = User.objects.get(id=payload["user_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

  • 토큰이 발급되면 request 헤더에 담기기 때문에 request 헤더에서 "Authorization"키에 해당하는 값을 가져온다. 이때 토큰이 없을 경우 None이 리턴된다. None을 받는 회원에게 비회원 뷰를 보여주던지, 아니면 Except에서 KeyError잡아 로그인 화면으로 유도하던지 등의 처리를 할 수 있다.

  • jwt.decode()로 페이로드에 담긴 user_id를 가져온 후 데이터 베이스에서 id가 user_id와 같은 유저의 객체를 가져온 뒤 request.user에 담는다.

발생할 수 있는 에러

  • jwt.exceptions.DecodeError:
    -> access_token이 None이거나 header/payload/signature가 손상되었을때. (InvalidSignatureError가 있지만 이는 DecodeError를 인자로 받기 때문에 DecodeError로만 처리해줘도 됨)
  • User.DoesNotExist: 토큰을 복호화하여 얻은 user_id가 데이터베이스 상에 존재하지 않을 때 처리하는 에러이다.


토큰 인증이 필요한 이유

토큰 인증이 필요한 이유는 바로 HTTP의 stateless한 특성때문이다. 클라이언트와 서버는 한번 연결이 되어 응답을 마치면 연결을 끊어버려 (Connectless) 클라이언트의 상태를 저장하지 않는다. 따라서 클라이언트가 로그인이 된 유효한 사용자인지도 모르기 때문에 매번 로그인이 필요한 행위를 할 때마다 로그인 정보를 함께 전달해야할 것이다.

하지만 이 토큰을 사용하면 매번 로그인 정보(아이디, 패스워드)를 전달하지 않고도 토큰만 인증하여 요청에 대한 권한이 있는지 확인 할 수 있다.

profile
Start fast to fail fast

0개의 댓글