본문 바로가기

TIL 및 WIL/TIL (Today I Learned)

[TIL] 2022.08.05 (Django DRF JWT 복습)

지난번 DRF에서 JWT 토큰 인증 방식을 사용하는 것에 대해 공부하는 시간을 가졌었다.

오늘은 그에 이어 다시금 복습하고 넘어가는 것을 진행하였다.

 

https://sdrtst.tistory.com/121

 

[TIL] 2022.07.26 (Django DRF JWT)

오늘은 프로젝트를 진행하면서 공부하고자 하는 내용 중 JWT에 대해 팀원들과 함께 알아보고자 하였다. JWT란? - Json Web Token의 약자 - 모바일 또는 웹의 사용자 인증을 위해 사용되는 암호화된 토

sdrtst.tistory.com

 

JWT란?
- Json Web Token의 약자
- Json 포맷을 이용하여 사용자에 대한 정보를 저장하는 클레임(Claim) 기반의 토큰 인증 방식
- 모바일 또는 웹에서 로그인한 사용자들의 정보를 포함하여 인증을 위해 사용되는 암호화 토큰
- 많은 토큰 인증 방식 중 가장 많이 사용되는 토큰 인증 방식

 

사용자 인증 방식에는 다양한 인증 방식들이 존재하는데 왜 JWT 토큰 인증 방식을 많이 사용하는 것일까?

 

일반적인 사용자 인증 방식에는 다음과 같은 문제점이 있기 때문이다.

 

1. 발급받은 토큰을 만료시킬 방법이 없다.
2. 발급받은 토큰을 검사하거나 처리할 때마다 데이터베이스에 접근해야 하므로 시스템에 부담이 커진다.
3. 모바일 또는 웹 사용자가 로그인 및 로그아웃을 할 경우 토큰을 관리할 방법이 없다.

 

이러한 이유 때문에 사용자의 정보를 지닌 데이터를 Json의 형태로 담아서 사용할 수 있게 하는 클레임(Claim) 기반의 토큰 인증 방식을 사용하여 JWT 토큰 인증 방식을 많이 사용하게 되었다.

 

JWT 토큰의 구조는 총 3가지로 구성되어 있는데, 헤더(Header), 페이로드(Payload), 서명(Verify_Signature)으로 구성되어 있다.

 

간단하게 JWT 각 구조들에 대해서 알아보도록 하자.

 

헤더(Header) : 서명 시(Signature) 시 사용한 암호화 알고리즘, 토큰 타입, key_id 등의 정보들을 지닌다.
페이로드(Payload) : 사용자 정보를 인증할 때 사용하는 데이터 필드(Claim)들을 지닌다.
서명(Verify_Signature) : 인코딩 된 Header, Payload, Secret_Key 3가지 정보들을 지닌다.

 

JWT 토큰의 구조

 

실제 Django 프로젝트에서 DRF JWT를 적용시키는 과정을 진행해보았다.

 

DRF JWT를 사용하기 위해서는 해당 모듈을 설치해주어야 한다.

명령어는 다음과 같다.

 

$ pip install djangorestframework-simplejwt

 

해당 패키지 설치가 끝났다면 settings.py에 'rest_framework_simplejwt'와 인증 방식을 추가하고 기본으로 제공하는 JWT View를 위한 URL 설정을 위해 urls.py에 다음 정보들을 적어준다.

 

# settings.py

INSTALLED_APPS = [
    ...
    'rest_framework_simplejwt',
]

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'),
]

 

만약 JWT 토큰 인증 방식에 대한 세부적인 설정을 원한다면 settings.py 안에 SIMPLE_JWT를 사용하여 세부적인 설정을 해줄 수 있다.

 

# settings.py

from datetime import timedelta

SIMPLE_JWT = {
    # Access 토큰 유효 시간 설정하기
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=50),
    # 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),
}

 

이제 해당 JWT 토큰을 발급받아보도록 해보자.

Postman을 이용하여 다음 JWT 토큰 URL로 유저 정보를 입력하여 토큰이 잘 나오는지 확인을 해보았다.

 

토큰 발급

 

정상적으로 access_token과 refresh_token이 발급된 것을 볼 수 있었다.

 

refresh_token은 해당 access_token을 재발급받을 때 사용하는 토큰이기 때문에 access_token을 가지고 해당 유저의 정보를 조회해보기로 하였다.

 

access_token을 이용한 유저 정보 조회

 

access_token을 사용할 때는 해당 토큰 앞에 Bearer를 붙여 사용해주면 된다.

 

이후 Django 프로젝트 중 이전에 타임어택으로 진행하였던 프로젝트인 '미니 채용 관리 시스템' 프로젝트를 가져와서 해당 JWT 토큰을 적용해보도록 하였다.

 

위에서 적어두었던 방식을 그대로 사용하여 해당 프로젝트에 적용을 해주었다.

그리고 채용관리를 위한 새로운 Apply 모델을 만들어주었다.

 

# post/models.py

class Apply(models.Model):
    user = models.ForeignKey(User, verbose_name="지원자", on_delete=models.CASCADE)
    jobpost = models.ForeignKey(JobPost, verbose_name="채용공고", on_delete=models.CASCADE)
    created_at = models.DateTimeField("지원날짜", auto_now_add=True)

    class Meta:
        db_table = 'applies'

 

모델을 설정해주면 해당 모델이 변경이 되었으므로 다음 명령어들을 통해서 모델을 DB 스키마(Schema)에 적용을 해주도록 했다.

 

$ python manage.py makemigrations
$ python manage.py migrate

 

이후 해당 모델을 사용하여 직렬화를 위한 Serializer 설정을 해주었다.

 

# post/serializers.py

from .models import Apply

class ApplySerializer(serializers.ModelSerializer):
    class Meta:
        model = Apply
        fields = '__all__'

 

이제 사용할 준비가 끝나고 실제로 JWT를 사용하여 채용공고 등록을 진행해보도록 하기 위해 views.py 설정을 해주었다.

 

# post/views.py

from rest_framework_simplejwt.authentication import JWTAuthentication
from .models import Apply
from .serializers import ApplySerializer

class ApplyView(APIView):
    authentication_classes = [JWTAuthentication]

    def post(self, request):
        request.data["user"] = request.user.id

        apply_serializer = ApplySerializer(data=request.data)

        if apply_serializer.is_valid():
            apply_serializer.save()
            return Response(apply_serializer.data, status=status.HTTP_200_OK)

        return Response(apply_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 

설정을 해줬으니 Postman에서 확인을 해주고자 하였다.

 

먼저 해당 토큰을 발급받기 위해 해당 유저의 email과 password를 넣어서 토큰을 발급해주었다.

 

JWT 토큰 발급

 

이제 채용공고 API에 발급받은 access_token을 넣어주고 채용공고가 저장이 되는지 확인을 해주었다.

 

access_token 적용
채용공고 등록

 

Postman을 통해 해당 채용공고를 저장하고 DB에서 확인을 해보았다.

 

채용공고 DB

 

정상적으로 잘 저장된 것을 볼 수 있었다.

 

JWT 1 Link : https://sdrtst.tistory.com/135

 

[JWT] Django Rest Framework에서 JWT 사용하기(1)

Django 프로젝트에서 DRF를 이용하여 JWT를 사용하는 방법에 대해 공부해보도록 했다. JWT란? - Json Web Token의 약자 - Json 포맷을 이용하여 사용자에 대한 정보를 저장하는 클레임(Claim) 기반의 토큰 인

sdrtst.tistory.com

JWT 2 Link : https://sdrtst.tistory.com/136

 

[JWT] Django Rest Framework에서 JWT 사용하기(2)

실제로 DRF에서 JWT를 이용하여 코드를 작성해 보기로 했다. 코드 예시로는 '미니 채용 관리 시스템'인 타임어택 테스트 코드를 이용하여 연습을 해보기로 하였다. 1. 프로젝트에 jwt 인증을 사용해

sdrtst.tistory.com

 

-

 

오늘은 JWT 토큰 인증 방식에 대해 다시금 공부하여 복습하는 시간을 가져보았다.

 

실제 진행하고 있는 프로젝트에서 JWT 토큰 인증 방식을 사용하기 때문에 저번에 공부했던 것을 복습하게 되었는데, 기억을 더듬으며 공부하니 잘 이해할 수 있게 된 것 같다.

 

:P