본문 바로가기
DEV/Web 개발

Web 개발 :: 파이썬 Django Rest Framework(6) _ token, permission

by 올커 2022. 10. 30.

DRF(Django Rest Framework)(6) _ token, permission

01. JWT Payload Customizing

 - 이제 JWT에서 확인할 수 있는 Payload란을 커스터마이징해보려 한다.

   해당내용은 참고 링크의 공식문서 Customizing token claims를 참고해도 된다.(※ 참고 링크)

 - 먼저 views.py에는 CustomTokenObtainPariSerializer라는 클래스를 만든다. 이 때 TokenObtainPairView를 임포트한다.

# users/views.py
...
from rest_framework_simplejwt.views import (TokenObtainPairView)
from users.serializers import UserSerializer, CustomTokenObtainPairSerializer

...
class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

 - CustomTokenObtainPairSerializer를 불러오기 위해 serializers.py에 클래스를 추가한다.

# users/serializers.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['email'] = user.email
        return token

 - urls.py에는 TokenObtainPairView를 views.CustomTokenObtainPairView로 바꾸어준다.

from rest_framework_simplejwt.views import (TokenObtainPairView,TokenRefreshView,)

urlpatterns = [
    ...
    path('api/token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
    ...
]

 - 파일을 저장 후 jwt에 접속하여 access token을 입혀보면 아래 payload에 email이라는 정보가 추가된 것을 확인할 수 있다.

 


 

02. Token lifetime과 permissions

 - payload 이외에 커스텀할 수 있는 부분은 공식문서의 settings를 확인해보면 알 수 있다. (※ 참고 링크)

   참고 링크의 내용을 가져와서 프로젝트폴더의 settings.py에 붙여넣고 내용을 수정해본다.

   여기서는 'ACCESS_TOKEN_LIFETIME': timedelta를 기존 5분에서 30분으로 늘려주어보았다.

# Django project settings.py

from datetime import timedelta
...

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': False,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    'JWK_URL': None,
    'LEEWAY': 0,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
    'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

 - views.py로 돌아와서 permissions를 임포트해오고, 아래와 같이 mockView를 생성한다.

   mockView에는 permission_classes라는 것을 만드는데 우항에서 permissions 모델을 IsAuthenticated로 선택한다.

# users/views.py

from rest_framework import status, permissions

...

class mockView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def get(self, request):
        return Response("get 요청")
# users/urls.py

urlpatterns = [
    ...
    path('mock/', views.mockView.as_view(), name='mock_view'),
    ...
]

 - 포트스맨에서 해당 URL로 GET 요청을 보내면 아래와 같이 로그인이 되어있지 않음을 확인할 수 있다.

 - 이 때 앞서 login request에서 확인했던 access token을 복사해와서 Headers에 입력해주어야 한다.

   key는 'Authorization'으로, 그리고 Value에는 'Bearer' 띄우고 '<복사한 토큰값>'으로 입력한다. 

 - 그럼 위 사진처럼 Response가 바뀐다. 그러나 아직 토큰이 유효하지 않다는 문구가 나오고 있다. 이는 이전에 로그인했던 계정이 시간이 지나 만료되었기 때문인데, 다시 로그인해주고, 위와 동일하게 access token을 복사해와서 적용하면 아래와 같이 정상적인 Response를 확인할 수 있다.


03. Refresh Token(재발급)

 - 토큰이 만료되었을 때 refresh토큰을 통해 다시 로그인하지 않아도 재발급받을 수 있다. 

   refresh 토큰을 복사하여 url을 입력 후 Body부분에 아래와 같이 dict형태로 "refresh" : "<복사한 토큰>" 으로 send해주면 아래 Response에 새로운 access 토큰이 출력된다.

 

 

 

 

반응형

댓글