Simple JWT: Access Token, Refresh Token 기본 설정과 활용법

Django REST Framework에서 JWT 인증을 구현하는 djangorestframework-simplejwt 라이브러리의 설정과 활용 방법

JWT의 특징

  • 자가수용적: 토큰 자체에 사용자 인증 정보를 포함하여 DB 조회 없이 사용자 확인 가능

  • 서명: 비밀 키로 서명되어 토큰 조작 여부 검증 가능

  • 구조: Header.Payload.Signature 세 부분으로 구성

Access Token vs Refresh Token

구분
Access Token
Refresh Token

목적

API 요청 시 사용자 인증

새로운 Access Token 발급

수명

짧다 (수분~수시간)

길다 (수일~수주)

저장 위치

메모리, localStorage

HttpOnly 쿠키 권장

전송 방식

Authorization Bearer 헤더

요청 본문으로 특정 엔드포인트 전송

기본 설정

라이브러리 설치

pip install djangorestframework-simplejwt

settings.py 설정

INSTALLED_APPS = [
    'rest_framework',
    'rest_framework_simplejwt',
    'rest_framework_simplejwt.token_blacklist',  # 로그아웃 기능용
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

urls.py 설정

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

상세 설정 옵션

from datetime import timedelta

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=15),  # 실무 권장: 15분~1시간
    "REFRESH_TOKEN_LIFETIME": timedelta(days=7),     # 실무 권장: 7일~30일
    "ROTATE_REFRESH_TOKENS": True,                   # 보안 강화를 위해 True 권장
    "BLACKLIST_AFTER_ROTATION": True,                # 사용된 토큰 재사용 방지
    "ALGORITHM": "HS256",
    "SIGNING_KEY": SECRET_KEY,
    "AUTH_HEADER_TYPES": ("Bearer",),
}

기본 사용법

토큰 발급 (로그인)

curl -X POST -H "Content-Type: application/json" \
-d '{"username": "testuser", "password": "password"}' \
http://127.0.0.1:8000/api/token/

API 요청

curl -X GET -H "Authorization: Bearer <access_token>" \
http://127.0.0.1:8000/api/protected-data/

토큰 재발급

curl -X POST -H "Content-Type: application/json" \
-d '{"refresh": "<refresh_token>"}' \
http://127.0.0.1:8000/api/token/refresh/

커스텀 토큰 페이로드

커스텀 Serializer 생성

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

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

설정 적용

SIMPLE_JWT = {
    "TOKEN_OBTAIN_SERIALIZER": "accounts.serializers.MyTokenObtainPairSerializer",
}

로그아웃 구현

from rest_framework_simplejwt.tokens import RefreshToken

class LogoutView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        try:
            refresh_token = request.data["refresh"]
            token = RefreshToken(refresh_token)
            token.blacklist()
            return Response(status=status.HTTP_205_RESET_CONTENT)
        except Exception:
            return Response(status=status.HTTP_400_BAD_REQUEST)

Last updated