bong-u/til

Django - JWT 인증

수정일 : 2024-06-28

JWT(Json Web Token)는 웹 표준으로, JSON 객체를 사용하여 정보를 안전하게 전달하는 방식이다.

JWT 인증 구현하기

장고에서는 djangorestframework-simplejwt 패키지를 사용하여 JWT 인증을 구현할 수 있다.

requirements

1pip install djangorestframework-simplejwt

settings.py

1INSTALLED_APPS = [
2    ...
3    'rest_framework',
4    'rest_framework_simplejwt',
5]
 1REST_FRAMEWORK = {
 2    # 기본 인증 클래스를 설정
 3    'DEFAULT_AUTHENTICATION_CLASSES': (
 4        'rest_framework_simplejwt.authentication.JWTAuthentication',
 5    ),
 6    # 기본 스키마 클래스를 설정, CoreAPI를 사용하여 자동으로 API 문서화를 생성
 7    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
 8    # 기본 권한 클래스를 설정, AllowAny를 사용하여 모든 요청을 허용
 9    'DEFAULT_PERMISSION_CLASSES': (
10        'rest_framework.permissions.AllowAny',
11    ),
12}
 1from datetime import timedelta
 2
 3SIMPLE_JWT = {
 4    # 액세스 토큰의 유효 기간을 설정
 5    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
 6    # 리프레시 토큰의 유효 기간을 설정
 7    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
 8    # 리프레시 토큰이 갱신될 때마다 새로운 리프레시 토큰을 발급할지 여부를 설정
 9    'ROTATE_REFRESH_TOKENS': False,
10    # 리프레시 토큰이 갱신된 후 이전 토큰을 블랙리스트에 추가할지 여부를 설정
11    'BLACKLIST_AFTER_ROTATION': True,
12
13    # JWT 토큰의 암호화 알고리즘을 설정
14    'ALGORITHM': 'HS256',
15    # JWT 토큰을 서명할 때 사용할 키를 설정
16    'SIGNING_KEY': SECRET_KEY,
17    # 토큰 검증에 사용할 공개 키를 설정
18    'VERIFYING_KEY': None,
19    # 토큰의 대상자(aud) 클레임을 설정
20    'AUDIENCE': None,
21    # 토큰의 발급자(iss) 클레임을 설정
22    'ISSUER': None,
23
24    # 인증 헤더 타입을 설정
25    'AUTH_HEADER_TYPES': ('Bearer',),
26    # 인증 헤더의 이름을 설정
27    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
28    # 사용자 모델에서 사용자 ID 필드를 설정
29    'USER_ID_FIELD': 'id',
30    # JWT 토큰에서 사용자 ID를 저장할 클레임을 설정
31    'USER_ID_CLAIM': 'user_id',
32
33    # 인증에 사용할 토큰 클래스들을 설정
34    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
35    # 토큰의 유형을 저장할 클레임을 설정
36    'TOKEN_TYPE_CLAIM': 'token_type',
37}

urls.py

 1from django.urls import path
 2from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
 3from rest_framework_simplejwt.authentication import JWTAuthentication
 4
 5urlpatterns = [
 6    # JWT 토큰을 발급하는 뷰
 7   path("token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
 8    # JWT 토큰을 갱신하는 뷰
 9   path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
10]

views.py

 1from rest_framework import permissions
 2from rest_framework_simplejwt.authentication import JWTAuthentication
 3from drf_yasg.utils import swagger_auto_schema
 4
 5
 6class PasteView(APIView):
 7
 8    def get(self, request):
 9        ...
10
11    def post(self, request):
12        ...
13
14   def get_permissions(self):
15        # SAFE_METHODS : GET, HEAD, OPTIONS
16        if self.request.method in permissions.SAFE_METHODS:
17            self.permission_classes = [permissions.AllowAny]
18        else:
19            self.authentication_classes = [JWTAuthentication]
20            self.permission_classes = [permissions.IsAuthenticated]
21        return super().get_permissions()
22
23
24class PasteDetailView(APIView):
25
26    def get(self, request, pk):
27        ...
28
29    def put(self, request, pk):
30        ...
31
32    def delete(self, request, pk):
33        ...
34
35    def get_permissions(self):
36        # SAFE_METHODS : GET, HEAD, OPTIONS
37        if self.request.method in permissions.SAFE_METHODS:
38            self.permission_classes = [permissions.AllowAny]
39        else:
40            self.authentication_classes = [JWTAuthentication]
41            self.permission_classes = [permissions.IsAuthenticated]
42        return super().get_permissions()
43

결과

  • TokenObtainPairView를 통해 access token과 refresh token을 발급받을 수 있다.
  • TokenRefreshView를 통해 refresh token을 사용하여 access token을 갱신할 수 있다.
  • access token과 refresh token은 settings.py에서 설정한 유효 기간에 따라 만료된다.

Blacklist 적용

settings.py

1INSTALLED_APPS = [
2    ...
3    'rest_framework_simplejwt.token_blacklist',
4]
1SIMPLE_JWT = {
2    ...
3    # 블랙리스트에 토큰을 추가할 때 사용할 모델을 설정
4    'BLACKLIST_AFTER_ROTATION': True,
5}

결과

  • TokenRefreshView를 통해 토큰이 재발급될 때, 이전 refresh token을 블랙리스트에 추가한다.