본문 바로가기
카테고리 없음

백엔드) simple jwt를 사용한 회원가입/탈퇴 구현 코드 해설

by abccoco 2022. 6. 30.

프로젝트에서 사용했던 simplejwt를 이용해 회원가입 탈퇴를 구현해보자

이번 프로젝트에서는 백엔드와 프론트엔드를 분리해서 작업했던 첫 프로젝트였다.

프론트와 백의 코드들을 연결해서 회원가입 기능을 구현해보자.

각 코드에 대한 해설은 주석으로 확인 할 수 있다.

 

simple jwt를 사용한 회원가입은 Local Storage 에 데이터를 저장한다.

이전에 사용했던 세션을 사용한 쿠키에 저장하는 방식이 아니라는 점을 먼저 꼭 기억하자.

Local Storage 이미지

우선은 백엔드에 코드를 작성해보자!

프론트와 백 모두 코드가 길지는 않다. 다만 simple jwt 를 사용하기 위해 필요한 설정들을 빼 놓으면 안 된다.

 

backend code

  • settings.py 에서 필요한 설정들을 하자.

apps에 simpeljwt를 추가해주기 위해 먼저

rest_framework를 추가 해주고 rest_framework_simpeljwt 를 추가해 준다.

# pip install djangorestframework 여건 당연하게 인스톨
pip install djangorestframework-simplejwt

다음으로 corsheaders 도 추가 해 주었는데 이걸 추가한 이유는

백엔드와 프론트엔드의 url이 다를 경우 (5000,5500) / 오리진이 다른 경우,

보안 이슈가 생겨 에러가 발생하기 때문에 url 이 달라도 이슈 내지 않아도 돼 라는 말을 컴퓨터에 해주기 위해

corsheaders 를 추가해 준다.

# cors 공식 참조 문서
https://pypi.org/project/django-cors-headers/
pip install django-cors-headers

settings.py

middleware 에도 cors를 추가해준다.

MIDDLEWARE = [
    ...,
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...,
]

이것도 추가

CORS_ORIGIN_ALLOW_ALL = True

 

cors 세팅은 끝났고 다시 simplejwt 로 돌아오자!

rest_framework 에서도 jwt를 추가해 준다.

 

SIMPLE_JWT 를 추가하면

jwt 설정이 가능하다.

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

 

  • urls.py를 작성해 보자.
# urls.py
urlpatterns = [
	# 회원가입 페이지로 들어왔을 때('') UserView 를 실행하도록 한다.
    # UserView 는 class 형 view 이므로 .as_view() 를 추가해 준다.
    path('', views.UserView.as_view()),
    # 아래 두가지 url은 jwt 에서 제공하는 기능으로 추가해 주기만 하면 jwt 방식의 로그인이 가능하다.
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    ]

 

  • urls.py에서 연결한 views.py 의 view를 보도록 하자.
# views.py
from requests import Response
from user.serializers import UserSerializer


class UserView(APIView):
    def post(self, request):
        # serializer의 data 인자에는 model로 지정 된 테이블의 field:value를 dictionary로 넘겨준다.
        user_serializer = UserSerializer(data=request.data)
        # serializer validator를 통과하지 않을 경우 .is_valid()가 False로 return된다.
        if user_serializer.is_valid():
            # validator를 통과했을 경우 데이터 저장
            user_serializer.save()
            return Response({"message": "정상"}, status=status.HTTP_200_OK)
        
        # .errors에는 validator에 실패한 필드와 실패 사유가 담겨져 있다.
        return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 

  • view.py에서 연결한 serializers.py 의 class를 작성해 보자
# serializers.py
from rest_framework import serializers
from user.models import User as UserModel

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserModel
        fields = ["fullname", "username", "password"]

    def create(self, validated_data):
        password = validated_data.pop("password", None)
        user = UserModel(**validated_data)
        # set_password() 를 사용해 헤싱을 해준다.
        user.set_password(password)
        user.save()

        return user

 

여기까지 백엔드 코드 작성을 완료했다.

다음 글에서 프론트엔드와 백엔드를 어떻게 연결해 기능을 구현하는지 알아보도록 하자.

댓글