Study/django

django의 Simple-JWT의 views.py와 serializers.py 정리

bluebamus 2025. 4. 1. 19:15

공식 매뉴얼 : https://django-rest-framework-simplejwt.readthedocs.io/en/latest/rest_framework_simplejwt.html

 

1. Simple-JWT의 views.py 클래스 매뉴얼

   1.1 TokenViewBase

      1.1.1. 설명:

         - JWT 관련 뷰 클래스들의 기본 베이스 클래스로, Django REST Framework의 GenericAPIView를 상속받아 구현됨.

 

      1.1.2. 상속:

         - GenericAPIView

 

      1.1.3. 역할:

         - 공통 토큰 처리 로직과 설정을 포함하여 다른 뷰들이 이를 상속받아 사용하도록 설계됨.

 

      1.1.4. 사용 예제:

# TokenViewBase를 상속받아 커스텀 토큰 뷰를 작성할 수 있습니다.
from rest_framework.generics import GenericAPIView

class MyCustomTokenView(TokenViewBase):
    """
    MyCustomTokenView는 TokenViewBase를 상속받아
    사용자 정의 토큰 발급 로직을 구현한 예제입니다.
    """
    def post(self, request, *args, **kwargs):
        # 여기에 토큰 발급 로직을 구현합니다.
        return self.create(request, *args, **kwargs)

 

   1.2 TokenObtainPairView

      1.2.1. 설명:

         - 사용자 자격 증명을 검증하고, Access Token과 Refresh Token을 동시에 발급하는 뷰이다. 주로 로그인 시 사용됨.

 

      1.2.2. 상속:

         - TokenViewBase

 

      1.2.3. 역할:

         - 사용자가 올바른 자격 증명을 제출하면, 두 종류의 토큰을 발급하여 클라이언트에게 전달.

 

      1.2.4. 사용 예제:

from rest_framework.response import Response

class TokenObtainPairView(TokenViewBase):
    """
    사용자의 자격 증명을 기반으로 Access Token과 Refresh Token을 생성합니다.
    """
    def post(self, request, *args, **kwargs):
        # serializer를 통해 자격 증명 검증 및 토큰 생성
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

 

   1.3 TokenRefreshView

      1.3.1. 설명:

         - 유효한 Refresh Token을 제공받아 새로운 Access Token을 발급하는 뷰이다.

 

      1.3.2. 상속:

         - TokenViewBase

 

      1.3.3. 역할:

         - 만료되지 않은 Refresh Token을 입력 받아, 새로운 Access Token을 생성해 반환.

 

      1.3.4. 사용 예제:

class TokenRefreshView(TokenViewBase):
    """
    Refresh Token을 이용하여 새로운 Access Token을 생성합니다.
    """
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

 

   1.4 TokenObtainSlidingView

      1.4.1. 설명:

         - Sliding Token 방식을 사용하여 Access Token과 새로운 Refresh Token을 생성하는 뷰이다.

 

      1.4.2. 상속:

         - TokenViewBase

 

      1.4.3. 역할:

         - Sliding Token 방식은 사용자 활동이 지속되는 동안 토큰의 유효기간을 갱신하는 특성이 있음.

 

      1.4.4. 사용 예제:

class TokenObtainSlidingView(TokenViewBase):
    """
    Sliding Token을 사용하여 Access Token과 Refresh Token을 생성합니다.
    """
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

 

   1.5 TokenRefreshSlidingView

      1.5.1. 설명:

         - Sliding Token의 Refresh Token을 갱신하고 새로운 Access Token을 발급하는 뷰이다.

 

      1.5.2. 상속:

         - TokenViewBase

 

      1.5.3. 역할:

         - 사용자가 Sliding Token을 제출하면, 갱신 과정을 거쳐 새로운 Access Token을 제공.

 

      1.5.4. 사용 예제:

class TokenRefreshSlidingView(TokenViewBase):
    """
    Sliding Token의 Refresh Token을 갱신하고 새로운 Access Token을 생성합니다.
    """
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

 

   1.6 TokenVerifyView

      1.6.1. 설명:

         - 전달받은 토큰이 유효한지를 검증하는 뷰이다.

 

      1.6.2. 상속:

         - TokenViewBase

 

      1.6.3. 역할:

         - 토큰이 올바른 형식 및 서명을 가지고 있는지 확인하여, 유효한 토큰인지 검증.

 

      1.6.4. 사용 예제:

class TokenVerifyView(TokenViewBase):
    """
    제공된 토큰이 유효한지를 검증합니다.
    """
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 유효하면 success 응답 반환
        return Response({"detail": "Token is valid"})

 

   1.7 TokenBlacklistView

      1.7.1. 설명:

         - 특정 토큰을 블랙리스트에 추가하여 해당 토큰의 사용을 무효화하는 뷰이다.

 

      1.7.2. 상속:

         - TokenViewBase

 

      1.7.3. 역할:

         - 로그아웃 시나 기타 토큰 폐기 상황에서 사용자가 더 이상 해당 토큰을 사용할 수 없도록 함.

 

      1.7.4. 사용 예제:

class TokenBlacklistView(TokenViewBase):
    """
    특정 토큰을 블랙리스트에 추가하여 무효화합니다.
    """
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 블랙리스트 처리 로직 구현 후 성공 응답 반환
        return Response({"detail": "Token has been blacklisted"})

 

2. Simple-JWT의 serializers.py 클래스 매뉴얼

   2.1 TokenObtainSerializer

      2.1.1. 설명:

         - 로그인 시 사용자의 자격 증명을 받아 Access Token을 발급하는 기본 시리얼라이저이다.

 

      2.1.2. 역할:

         - 사용자의 아이디/비밀번호 등 자격 증명을 검증하고, 이에 따라 Access Token을 생성.

 

      2.1.3. 사용 예제:

from rest_framework import serializers

class TokenObtainSerializer(serializers.Serializer):
    """
    사용자의 자격 증명을 받아 Access Token을 발급합니다.
    """
    username = serializers.CharField()
    password = serializers.CharField(write_only=True)

    def validate(self, attrs):
        # 사용자 인증 및 Access Token 생성 로직
        # (예제에서는 간단히 검증 통과 가정)
        attrs['access_token'] = "생성된_액세스_토큰"
        return attrs

 

   2.2 TokenObtainPairSerializer

      2.2.1. 설명:

         - 사용자 자격 증명을 기반으로 Access Token과 Refresh Token을 함께 발급하는 시리얼라이저이다.

 

      2.2.2. 역할:

         - 두 종류의 토큰을 함께 생성하여 클라이언트에 반환.

 

      2.2.3. 사용 예제:

class TokenObtainPairSerializer(TokenObtainSerializer):
    """
    사용자의 자격 증명을 받아 Access Token과 Refresh Token을 발급합니다.
    상속: TokenObtainSerializer를 상속받아 확장합니다.
    """
    def validate(self, attrs):
        data = super().validate(attrs)
        # 추가로 Refresh Token 생성 로직
        data['refresh_token'] = "생성된_리프레시_토큰"
        return data

 

   2.3 TokenObtainSlidingSerializer

      2.3.1. 설명:

         - Sliding Token 방식으로 Access Token과 Refresh Token(혹은 슬라이딩 토큰)을 생성하는 시리얼라이저이다.

 

      2.3.2. 역할:

         - 사용자의 자격 증명을 받아 Sliding Token 기반 인증 정보를 생성.

 

      2.3.3. 사용 예제:

class TokenObtainSlidingSerializer(TokenObtainSerializer):
    """
    Sliding Token 방식을 사용하여 토큰을 생성합니다.
    """
    def validate(self, attrs):
        data = super().validate(attrs)
        # Sliding Token 관련 추가 로직
        data['sliding_token'] = "생성된_슬라이딩_토큰"
        return data

 

   2.4 TokenRefreshSerializer

      2.4.1. 설명:
         - 유효한 Refresh Token을 사용하여 새로운 Access Token을 생성하는 시리얼라이저이다.

 

      2.4.2. 역할:

         - Refresh Token의 유효성을 검증한 후, 새로운 Access Token을 발급.

 

      2.4.3. 사용 예제:

class TokenRefreshSerializer(serializers.Serializer):
    """
    Refresh Token을 사용하여 새로운 Access Token을 생성합니다.
    """
    refresh = serializers.CharField()

    def validate(self, attrs):
        refresh_token = attrs.get('refresh')
        # Refresh Token 검증 및 새로운 Access Token 생성 로직
        attrs['access_token'] = "새로운_액세스_토큰"
        return attrs

 

   2.5 TokenRefreshSlidingSerializer

      2.5.1. 설명:

         - Sliding Token을 사용하여 Refresh Token을 갱신하고, 새로운 Access Token을 생성하는 시리얼라이저이다.

 

      2.5.2. 역할:

         - Sliding Token 방식에서 토큰 갱신 로직을 수행.

 

      2.5.3. 사용 예제:

class TokenRefreshSlidingSerializer(serializers.Serializer):
    """
    Sliding Token 기반으로 Refresh Token을 갱신하고 새로운 Access Token을 생성합니다.
    """
    sliding_token = serializers.CharField()

    def validate(self, attrs):
        sliding_token = attrs.get('sliding_token')
        # Sliding Token 갱신 로직 구현
        attrs['access_token'] = "갱신된_액세스_토큰"
        return attrs

 

   2.6 TokenVerifySerializer

      2.6.1. 설명:

         - 토큰의 유효성을 검증하는 데 사용되는 시리얼라이저이다.

 

      2.6.2. 역할:

         - 입력받은 토큰의 유효성(서명, 만료 등)을 검증.

 

      2.6.3. 사용 예제:

class TokenVerifySerializer(serializers.Serializer):
    """
    제공된 토큰의 유효성을 검증합니다.
    """
    token = serializers.CharField()

    def validate(self, attrs):
        token = attrs.get('token')
        # 토큰 검증 로직
        # 유효하면 추가 처리 없이 반환
        return attrs

 

   2.7 TokenBlacklistSerializer

      2.7.1. 설명:

         - 특정 토큰을 블랙리스트에 추가하는 데 사용되는 시리얼라이저이다.

 

      2.7.2. 역할:

         - 토큰 폐기를 위한 요청 데이터를 검증하고, 블랙리스트 처리 로직과 연결.

 

      2.7.3. 사용 예제:

class TokenBlacklistSerializer(serializers.Serializer):
    """
    특정 토큰을 블랙리스트에 추가하여 무효화합니다.
    """
    token = serializers.CharField()

    def validate(self, attrs):
        token = attrs.get('token')
        # 토큰 블랙리스트 등록 로직
        return attrs

 

3. 각 항목별 사용 예시 코드

   - 아래는 위에서 설명한 각 뷰와 시리얼라이저를 사용하는 예시 코드이다.

 

   3.1 URL 설정 (urls.py)

# urls.py
from django.urls import path
from .views import (
    TokenObtainPairView,
    TokenRefreshView,
    TokenObtainSlidingView,
    TokenRefreshSlidingView,
    TokenVerifyView,
    TokenBlacklistView,
)

urlpatterns = [
    # 사용자의 로그인: Access 및 Refresh 토큰 발급
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    # Refresh Token을 통한 Access Token 재발급
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    # Sliding Token을 이용한 토큰 발급
    path('api/token/sliding/', TokenObtainSlidingView.as_view(), name='token_obtain_sliding'),
    # Sliding Token 갱신
    path('api/token/sliding/refresh/', TokenRefreshSlidingView.as_view(), name='token_refresh_sliding'),
    # 토큰 검증
    path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
    # 토큰 블랙리스트 처리 (예: 로그아웃)
    path('api/token/blacklist/', TokenBlacklistView.as_view(), name='token_blacklist'),
]

 

   3.2 뷰와 시리얼라이저 사용 예시 (views.py 내)

# views.py
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from .serializers import (
    TokenObtainPairSerializer,
    TokenRefreshSerializer,
    TokenObtainSlidingSerializer,
    TokenRefreshSlidingSerializer,
    TokenVerifySerializer,
    TokenBlacklistSerializer,
)

class TokenViewBase(GenericAPIView):
    """
    모든 토큰 관련 뷰의 베이스 클래스.
    공통으로 사용되는 serializer_class, 인증 로직 등을 정의합니다.
    """
    # 각 뷰에서 serializer_class를 재정의하여 사용합니다.
    pass

class TokenObtainPairView(TokenViewBase):
    """
    사용자 로그인 시 Access Token과 Refresh Token을 발급합니다.
    상속: TokenViewBase
    """
    serializer_class = TokenObtainPairSerializer

    def post(self, request, *args, **kwargs):
        # 요청 데이터를 통해 시리얼라이저 검증 후 토큰 생성
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenRefreshView(TokenViewBase):
    """
    Refresh Token을 이용하여 새로운 Access Token을 발급합니다.
    상속: TokenViewBase
    """
    serializer_class = TokenRefreshSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenObtainSlidingView(TokenViewBase):
    """
    Sliding Token을 이용하여 토큰을 생성합니다.
    상속: TokenViewBase
    """
    serializer_class = TokenObtainSlidingSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenRefreshSlidingView(TokenViewBase):
    """
    Sliding Token의 Refresh Token을 갱신합니다.
    상속: TokenViewBase
    """
    serializer_class = TokenRefreshSlidingSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenVerifyView(TokenViewBase):
    """
    제공된 토큰의 유효성을 검증합니다.
    상속: TokenViewBase
    """
    serializer_class = TokenVerifySerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response({"detail": "Token is valid"})

class TokenBlacklistView(TokenViewBase):
    """
    특정 토큰을 블랙리스트에 추가하여 무효화합니다.
    상속: TokenViewBase
    """
    serializer_class = TokenBlacklistSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 블랙리스트 처리 로직 구현 (예: 데이터베이스에 기록)
        return Response({"detail": "Token has been blacklisted"})

 

4. 최종 프로젝트 예제

   - 아래는 간단한 Django REST Framework 프로젝트 시나리오이다.
   - 예제 시나리오는 “사용자 로그인/로그아웃 및 토큰 갱신” 기능을 제공하며, Simple-JWT의 모든 클래스들을 적절히 활용하여 구현한다.

 

   4.1 프로젝트 구조 예시

my_jwt_project/
├── manage.py
├── my_jwt_app/
│   ├── __init__.py
│   ├── urls.py
│   ├── views.py       # 위에 작성한 토큰 뷰 클래스들이 포함됨
│   ├── serializers.py # 위에 작성한 시리얼라이저 클래스들이 포함됨
│   └── models.py
└── my_jwt_project/
    ├── __init__.py
    ├── settings.py    # JWT 설정 포함
    ├── urls.py        # 전체 URL 라우팅
    └── wsgi.py

 

   4.2 settings.py (JWT 관련 설정)

# my_jwt_project/settings.py
INSTALLED_APPS = [
    # Django 기본 앱들...
    'rest_framework',
    'my_jwt_app',  # 토큰 관련 기능을 포함하는 앱
]

REST_FRAMEWORK = {
    # JWT 인증 클래스를 기본 인증 클래스로 설정
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

# Simple-JWT의 추가 설정 (옵션)
from datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
}

 

   4.3 전체 URL 라우팅 (프로젝트 urls.py)

# my_jwt_project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    # my_jwt_app 내에 정의한 토큰 URL들을 include 합니다.
    path('api/', include('my_jwt_app.urls')),
]

 

   4.4 최종 프로젝트 예제 코드 (예: views.py 내 추가 사용자 관련 뷰)

# my_jwt_app/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated

# 위에서 정의한 Token 관련 뷰들을 이미 포함하고 있으므로,
# 추가로 인증이 필요한 사용자 정보 API 예제를 추가합니다.

class UserProfileView(APIView):
    """
    인증된 사용자의 프로필 정보를 반환하는 뷰입니다.
    JWT 토큰이 유효한 경우에만 접근할 수 있습니다.
    """
    permission_classes = [IsAuthenticated]

    def get(self, request, format=None):
        # request.user는 JWT 인증을 통과한 사용자 정보를 포함합니다.
        user = request.user
        data = {
            "username": user.username,
            "email": user.email,
        }
        return Response(data)

 

   4.5 최종 프로젝트 사용 예시 시나리오

      4.5.1. 로그인 요청:

         - 클라이언트가 /api/token/ 엔드포인트에 사용자 자격 증명(username, password)을 POST 요청한다.
         - TokenObtainPairView와 TokenObtainPairSerializer가 이를 처리하여 Access Token과 Refresh Token을 반환한다.

 

      4.5.2. 토큰 검증:

         - 클라이언트는 JWT 토큰을 사용할 때 /api/token/verify/ 엔드포인트에 토큰을 제출하여 유효성을 확인할 수 있다.

 

      4.5.3. 토큰 갱신:

         - Access Token이 만료된 경우, /api/token/refresh/ 엔드포인트에 Refresh Token을 제출하여 새로운 Access Token을 발급받는다.

 

      4.5.4. 로그아웃 및 토큰 폐기:

         - 클라이언트는 /api/token/blacklist/ 엔드포인트에 현재 사용 중인 토큰을 제출하여 블랙리스트에 등록하고, 이후 해당 토큰은 사용되지 않는다.

 

      4.5.5. 인증이 필요한 사용자 API 접근:

         - /api/profile/ (예: UserProfileView)를 호출하면 JWT 인증을 통해 사용자 프로필 정보를 확인할 수 있다.

 

5. 최종 프로젝트 전체 코드 예제

   - 아래는 위의 내용을 모두 포함한 최종 프로젝트의 주요 코드 예제이다.

# my_jwt_app/urls.py
from django.urls import path
from .views import (
    TokenObtainPairView,
    TokenRefreshView,
    TokenObtainSlidingView,
    TokenRefreshSlidingView,
    TokenVerifyView,
    TokenBlacklistView,
    UserProfileView,  # 사용자 프로필 정보 뷰
)

urlpatterns = [
    path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('token/sliding/', TokenObtainSlidingView.as_view(), name='token_obtain_sliding'),
    path('token/sliding/refresh/', TokenRefreshSlidingView.as_view(), name='token_refresh_sliding'),
    path('token/verify/', TokenVerifyView.as_view(), name='token_verify'),
    path('token/blacklist/', TokenBlacklistView.as_view(), name='token_blacklist'),
    path('profile/', UserProfileView.as_view(), name='user_profile'),
]
# my_jwt_app/views.py
from rest_framework.generics import GenericAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from .serializers import (
    TokenObtainPairSerializer,
    TokenRefreshSerializer,
    TokenObtainSlidingSerializer,
    TokenRefreshSlidingSerializer,
    TokenVerifySerializer,
    TokenBlacklistSerializer,
)

# --- 토큰 관련 뷰 ---
class TokenViewBase(GenericAPIView):
    """
    모든 토큰 관련 뷰의 공통 베이스 클래스입니다.
    """
    pass

class TokenObtainPairView(TokenViewBase):
    """
    사용자 로그인 시 Access Token과 Refresh Token을 발급합니다.
    """
    serializer_class = TokenObtainPairSerializer

    def post(self, request, *args, **kwargs):
        # 요청 데이터로부터 시리얼라이저를 초기화하고 검증합니다.
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenRefreshView(TokenViewBase):
    """
    Refresh Token을 사용하여 새로운 Access Token을 발급합니다.
    """
    serializer_class = TokenRefreshSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenObtainSlidingView(TokenViewBase):
    """
    Sliding Token을 이용하여 토큰을 생성합니다.
    """
    serializer_class = TokenObtainSlidingSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenRefreshSlidingView(TokenViewBase):
    """
    Sliding Token의 Refresh Token을 갱신하여 새로운 Access Token을 생성합니다.
    """
    serializer_class = TokenRefreshSlidingSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.validated_data)

class TokenVerifyView(TokenViewBase):
    """
    제공된 토큰의 유효성을 검증합니다.
    """
    serializer_class = TokenVerifySerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response({"detail": "Token is valid"})

class TokenBlacklistView(TokenViewBase):
    """
    특정 토큰을 블랙리스트에 추가하여 무효화합니다.
    """
    serializer_class = TokenBlacklistSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 여기서 실제 블랙리스트 로직을 수행합니다.
        return Response({"detail": "Token has been blacklisted"})

# --- 사용자 관련 뷰 ---
class UserProfileView(APIView):
    """
    인증된 사용자의 프로필 정보를 반환하는 뷰입니다.
    JWT 토큰 인증이 통과된 경우에만 접근 가능합니다.
    """
    permission_classes = [IsAuthenticated]

    def get(self, request, format=None):
        user = request.user  # JWT 인증을 통해 설정된 사용자 객체
        data = {
            "username": user.username,
            "email": user.email,
        }
        return Response(data)
# my_jwt_app/serializers.py
from rest_framework import serializers

class TokenObtainSerializer(serializers.Serializer):
    """
    사용자의 자격 증명을 받아 Access Token을 발급하는 기본 시리얼라이저입니다.
    """
    username = serializers.CharField()
    password = serializers.CharField(write_only=True)

    def validate(self, attrs):
        # 실제 인증 로직이 들어갈 자리입니다.
        attrs['access_token'] = "생성된_액세스_토큰"
        return attrs

class TokenObtainPairSerializer(TokenObtainSerializer):
    """
    사용자 자격 증명을 받아 Access Token과 Refresh Token을 함께 발급합니다.
    상속: TokenObtainSerializer를 확장합니다.
    """
    def validate(self, attrs):
        data = super().validate(attrs)
        # Refresh Token 생성 로직 추가
        data['refresh_token'] = "생성된_리프레시_토큰"
        return data

class TokenObtainSlidingSerializer(TokenObtainSerializer):
    """
    Sliding Token 방식을 사용하여 토큰을 생성합니다.
    """
    def validate(self, attrs):
        data = super().validate(attrs)
        # Sliding Token 생성 로직 추가
        data['sliding_token'] = "생성된_슬라이딩_토큰"
        return data

class TokenRefreshSerializer(serializers.Serializer):
    """
    Refresh Token을 사용하여 새로운 Access Token을 생성합니다.
    """
    refresh = serializers.CharField()

    def validate(self, attrs):
        # Refresh Token 검증 후 새로운 Access Token 생성
        attrs['access_token'] = "새로운_액세스_토큰"
        return attrs

class TokenRefreshSlidingSerializer(serializers.Serializer):
    """
    Sliding Token 기반 Refresh Token을 갱신하고, 새로운 Access Token을 생성합니다.
    """
    sliding_token = serializers.CharField()

    def validate(self, attrs):
        # Sliding Token 검증 후 갱신 로직 구현
        attrs['access_token'] = "갱신된_액세스_토큰"
        return attrs

class TokenVerifySerializer(serializers.Serializer):
    """
    제공된 토큰의 유효성을 검증합니다.
    """
    token = serializers.CharField()

    def validate(self, attrs):
        # 토큰 검증 로직 구현
        return attrs

class TokenBlacklistSerializer(serializers.Serializer):
    """
    특정 토큰을 블랙리스트에 추가하여 무효화합니다.
    """
    token = serializers.CharField()

    def validate(self, attrs):
        # 토큰 블랙리스트 등록 로직 구현
        return attrs

 

6. 주요 settings 정리

from datetime import timedelta
from django.conf import settings

# Django의 SECRET_KEY가 이미 설정되어 있다고 가정합니다.
SECRET_KEY = settings.SECRET_KEY

SIMPLE_JWT = {
    # ----------------------------------------------------------------------
    # Token Lifetime 관련 옵션
    # ----------------------------------------------------------------------
    # Access Token의 유효 기간. 기본적으로 1일 동안 유효함.
    'ACCESS_TOKEN_LIFETIME': timedelta(days=1),

    # Refresh Token의 유효 기간. 기본적으로 2일 동안 유효함.
    'REFRESH_TOKEN_LIFETIME': timedelta(days=2),

    # Refresh Token을 Access Token 갱신 시 새로 발급할지 여부
    # True: 새로운 Refresh Token 발급
    # False: 기존 Refresh Token 유지
    'ROTATE_REFRESH_TOKENS': False,

    # Refresh Token 회전 시 기존 토큰을 블랙리스트에 추가할지 여부
    # True: 기존 Refresh Token 무효화
    # False: 기존 Refresh Token 계속 사용 가능
    'BLACKLIST_AFTER_ROTATION': False,

    # 사용자가 JWT를 사용하여 로그인할 때, last_login 필드를 업데이트할지 여부
    'UPDATE_LAST_LOGIN': False,

    # ----------------------------------------------------------------------
    # 암호화 및 검증 관련 옵션
    # ----------------------------------------------------------------------
    # JWT 토큰의 서명에 사용되는 알고리즘 (예: HS256, RS256, ES256 등)
    'ALGORITHM': 'HS256',

    # JWT 서명에 사용되는 비밀 키 (HS256의 경우 필수)
    'SIGNING_KEY': SECRET_KEY,

    # JWT 서명을 검증할 때 사용되는 공개 키 (비대칭 암호화 알고리즘 사용 시 필요)
    'VERIFYING_KEY': None,

    # JWT 토큰의 Audience(대상) 지정
    'AUDIENCE': None,

    # JWT 토큰의 발급자(Issuer) 지정
    'ISSUER': None,

    # JSON Web Key (JWK) URL (공개 키를 가져오기 위한 URL, 필요시 설정)
    'JWK_URL': None,

    # 토큰 만료를 검증할 때 허용할 시계 차이(초 단위)
    'LEEWAY': 0,

    # ----------------------------------------------------------------------
    # HTTP Header 및 사용자 관련 옵션
    # ----------------------------------------------------------------------
    # HTTP 인증 헤더에서 허용할 토큰 타입 ('Bearer', 'JWT' 등)
    'AUTH_HEADER_TYPES': ('Bearer',),

    # HTTP 요청에서 토큰이 포함될 헤더 이름 (기본값: 'HTTP_AUTHORIZATION')
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',

    # User 모델에서 토큰에 저장할 식별자 필드 (예: 'id', 'username' 등)
    'USER_ID_FIELD': 'id',

    # 토큰에 저장될 사용자 식별자 클레임 이름 (예: 'user_id', 'sub' 등)
    'USER_ID_CLAIM': 'user_id',

    # 사용자 인증 규칙을 결정하는 함수 경로
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    # ----------------------------------------------------------------------
    # 토큰 클래스 및 관련 클레임 설정
    # ----------------------------------------------------------------------
    # JWT 토큰의 클래스 지정 ('AccessToken', 'SlidingToken' 등)
    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),

    # 토큰 타입을 나타내는 클레임의 이름 ('token_type' 등)
    'TOKEN_TYPE_CLAIM': 'token_type',

    # Token 기반 사용자 객체를 나타내는 클래스 (기본값: TokenUser)
    'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',

    # 토큰의 고유 식별자(JTI: JWT ID)
    'JTI_CLAIM': 'jti',

    # ----------------------------------------------------------------------
    # Sliding Token 관련 옵션
    # ----------------------------------------------------------------------
    # Sliding Token에서 Refresh 만료 시간 정보를 저장하는 클레임 이름
    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',

    # Sliding Token의 기본 유효 기간 (기본값: 5분)
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),

    # Sliding Token의 Refresh가 가능한 최대 기간 (기본값: 1일)
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),

    # ----------------------------------------------------------------------
    # JWT 쿠키 관련 옵션 (사용자가 필요에 따라 활성화 가능)
    # ----------------------------------------------------------------------
    # JWT를 쿠키에 저장할지 여부 (True로 설정하면 쿠키에 저장됨)
    'JWT_COOKIE': False,

    # Access Token을 저장할 쿠키 이름 (JWT_COOKIE=True일 때 사용)
    'JWT_ACCESS_COOKIE': 'access_token',

    # Refresh Token을 저장할 쿠키 이름 (JWT_COOKIE=True일 때 사용)
    'JWT_REFRESH_COOKIE': 'refresh_token',

    # Access Token을 저장할 쿠키 경로 (예: '/', '/api/', '/auth/' 등)
    'JWT_ACCESS_COOKIE_PATH': '/',

    # Refresh Token을 저장할 쿠키 경로 (예: '/', '/api/', '/auth/' 등)
    'JWT_REFRESH_COOKIE_PATH': '/',

    # 쿠키를 HTTP-only로 설정할지 여부 (XSS 공격 방지)
    'JWT_COOKIE_HTTPONLY': True,

    # 쿠키의 Secure 속성을 설정할지 여부 (HTTPS 환경에서만 쿠키 전송)
    # True: HTTPS 환경에서만 쿠키를 전송 (추천)
    # False: HTTP에서도 쿠키를 전송
    'JWT_COOKIE_SECURE': False,

    # 쿠키의 SameSite 속성을 설정 (CSRF 공격 방지)
    # - 'Lax': 기본적으로 허용되지만, 일부 요청에서 제한됨 (권장)
    # - 'Strict': 타 사이트에서의 모든 요청 차단 (보안 강화)
    # - 'None': 제약 없음 (하지만 Secure=True 필요)
    'JWT_COOKIE_SAMESITE': 'Lax',

    # ----------------------------------------------------------------------
    # 기타 옵션 (사용자가 필요에 따라 활성화 가능)
    # ----------------------------------------------------------------------
    # 'TOKEN_OBTAIN_SERIALIZER': 'path.to.custom.TokenObtainSerializer',
    # 'TOKEN_REFRESH_SERIALIZER': 'path.to.custom.TokenRefreshSerializer',
    # 'TOKEN_VERIFY_SERIALIZER': 'path.to.custom.TokenVerifySerializer',
    # 'TOKEN_BLACKLIST_SERIALIZER': 'path.to.custom.TokenBlacklistSerializer',
    # 'USER_SERIALIZER': 'path.to.custom.UserSerializer',  # 사용자 정보 직렬화 시 사용할 시리얼라이저
}