본문 바로가기

프로그래밍/Django개발(MAC OS)

Django Rest API 서버 만들기 요약 - Day 4 : 로그인 JWT

반응형

이번에는 로그인을 해볼 것입니다.

로그인을 하는 경우에는 USERNAME / password가 필요하죠. 이 두가지를 가지고 로그인을 하면 jwt token을 만들어서 리턴해주는 것입니다.

아래와 같이 작성해주면 됩니다.

@api_view(["POST"])
def login(request):
    username = request.data.get("username")
    password = request.data.get("password")
    if not username or not password:
        return Response(status=status.HTTP_400_BAD_REQUEST)
    user = authenticate(username=username, password=password)
    if user is not None:
        encoded_jwt = jwt.encode(
            {"id": user.pk}, settings.SECRET_KEY, algorithm="HS256"
        )
        return Response(data={"token": encoded_jwt})
    else:
        return Response(status=status.HTTP_401_UNAUTHORIZED)

 jwt는 토큰화 된것이기는 하나 이것은 해독이 아주 간단합니다. 그래서 jwt토큰을 만들 때에는 반드시 필요한 정보는 넣으면 안됩니다. 코드처럼 단순히 id만을 넣어주는 것이죠 다른 사람들에게느느 의미없는 데이터이죠?

그럼 왜 쓸까요? 그것은 jwt토큰으로 발행을 하면 누군가가 절대 변경할 수 없기 때문입니다. 우리가 jwt토큰을 만드는 이유는
데이터가 보내질때 변경이 일어났는가를 감지하기 위한 것이랍니다.

 

 

그럼 이제 내가 생성한 jwt의 값을 가지고 인증을 해야됩니다.

인증하는 방법은 custon authentication 의 예제를 참조하면 되는데요

config/authentication.py 파일을 만들고

그곳에다가 아래처럼 코드를 작성합니다.

import jwt
from django.conf import settings
from rest_framework import authentication
from users.models import User


class JWTAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        try:
            token = request.META.get("HTTP_AUTHORIZATION")
            if token is None:
                return None
            xjwt, jwt_token = token.split(" ")
            decoded = jwt.decode(jwt_token, settings.SECRET_KEY, algorithms=["HS256"])
            pk = decoded.get("pk")
            user = User.objects.get(pk=pk)
            return (user, None)
        except (ValueError, jwt.exceptions.DecodeError, User.DoesNotExist):
            return None

로직은 말그대로 jwt값을 디코드해서 pk값을 가져오는 것이고, 그값으로 user object를 가져오는 방식입니다.

이것을 사용하기 위해서는 settings.py에 restframework에서 auth 인증을 이걸로 하겠다고 지정해줘야합니다.

#config/settings.py

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 10,
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'config.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

이런 형태로 지정을 해줘야 합니다.

반응형