simplejwt
를 설치합니다. 기존 djangorestframework-jwt
는 더이상 업데이트가 되고 있지 않습니다.
$ pip install djangorestframework-simplejwt
JWT로 인증할 것 이기 때문에 settings.py
의 REST_FRAMEWORK
의 인증 방식을 변경(추가)해 줍니다.
settings.py
'DEFAULT_AUTHENTICATION_CLASSES': [
...
# JWT 인증 방식 추가하기
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
simplejwt
에서 제공하는 기본 JWT 인증을 사용할 것입니다. 따라서 인증 토큰 발급 urlpatterns
에 토큰 발급 view
를 추가해 줍니다.
user/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'),
...
]
JWT를 사용하기 위해 INSTALLED_APPS
에 'rest_framework_simplejwt'
추가해 줍니다.
drf_jwt/settings.py
INSTALLED_APPS = [
...
'rest_framework_simplejwt',
...
]
settings.py
에서 JWT
에 대한 설정을 부여할 수 있습니다. 기본적으로는 access
토큰과 refresh
토큰의 유효시간을 설정합니다.
drf_jwt/settings.py
from datetime import timedelta
...
SIMPLE_JWT = {
# Access 토큰 유효 시간 설정하기
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
# Refresh 토큰 유효 시간 설정하기
'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),
}
토큰에 담긴 사용자의 정보를 의미하는 claim
을 커스터마이징할 수도 있습니다. Serializer
를 활용하여 simplejwt
에서 제공하는 기본 정보 이외에 우리가 포함하고 싶은 정보를 토큰에 추가적으로 넣어봅니다.
user/jwt_claim_serializer.py
생성 후 작성. 기본 토큰에는 user_id
만 반환 되는 것을 알 수 있는데요, 여기에 id
, username
클레임을 같이 삽입해 보겠습니다.from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
# TokenObtainPairSerializer를 상속하여 클레임 설정
class SpartaTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
# 생성된 토큰 가져오기
token = super().get_token(user)
# 사용자 지정 클레임 설정하기.
token['id'] = user.id
token['username'] = user.username
return token
user/views.py
Serializer
구현은 매우 간단합니다. 위에서 만든 SpartaTokenObtainPairSerializer
클래스를 그대로 serializer_class
에 지정하겠습니다....
from user.jwt_claim_serializer import SpartaTokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
...
class SpartaTokenObtainPairView(TokenObtainPairView):
serializer_class = SpartaTokenObtainPairSerializer
user/urls.py
urlpatterns
에 SpartaTokenObtainPairView
를 등록하여 응답할 수 있게 합니다....
from user.views import SpartaTokenObtainPairView
...
urlpatterns = [
...
path('api/sparta/token/', SpartaTokenObtainPairView.as_view(), name='sparta_token'),
...
]
이번엔 JWT를 이용해 인증된 사용자만 접근할 수 있는 view
를 만들어 보겠습니다. 유효한 access
토큰을 가진 사용자라면 인가된 사용자만 볼 수 있는 정보를 확인할 수 있습니다.
users/views.py
...
from rest_framework_simplejwt.authentication import JWTAuthentication
...
# 인가된 사용자만 접근할 수 있는 View 생성
class OnlyAuthenticatedUserView(APIView):
permission_classes = [permissions.IsAuthenticated]
# JWT 인증방식 클래스 지정하기
authentication_classes = [JWTAuthentication]
def get(self, request):
# Token에서 인증된 user만 가져온다.
user = request.user
print(f"user 정보 : {user}")
if not user:
return Response({"error": "접근 권한이 없습니다."}, status=status.HTTP_401_UNAUTHORIZED)
return Response({"message": "Accepted"})
user/urls.py
...
from user.views import OnlyAuthenticatedUserView
...
urlpatterns = [
...
path('api/authonly/', OnlyAuthenticatedUserView.as_view()),
...
]