지난 시간에는 로그인을 성공했을 시 토큰을 발급하는 것을 구현했다.
이번에는 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에 담는다.
토큰 인증이 필요한 이유는 바로 HTTP의 stateless한 특성때문이다. 클라이언트와 서버는 한번 연결이 되어 응답을 마치면 연결을 끊어버려 (Connectless) 클라이언트의 상태를 저장하지 않는다. 따라서 클라이언트가 로그인이 된 유효한 사용자인지도 모르기 때문에 매번 로그인이 필요한 행위를 할 때마다 로그인 정보를 함께 전달해야할 것이다.
하지만 이 토큰을 사용하면 매번 로그인 정보(아이디, 패스워드)를 전달하지 않고도 토큰만 인증하여 요청에 대한 권한이 있는지 확인 할 수 있다.