본문 바로가기

Django

DRF(Django REST framework)로 API 서비스 만들기-3

이제 유저 모델과 jwt 인증을 연결해줄 순서이다.

 

jwt 란? https://mangkyu.tistory.com/56

 

 

1. 라이브러리 설치

 

콘솔에서 해당 명령어를 입력한다. 

 

pip install djangorestframework-simplejwt

 

 

2. 설정 파일 수정

 

config/settings.py

 

...

from datetime import timedelta

…

INSTALLED_APPS = [
   …
    'rest_framework',
    'rest_framework_simplejwt',
]

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


SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=30),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,

    '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',
}

...

 

simplet jwt 부분에서 자신에게 맞게 설정 부분을 변경하면 된다.

 

 

 

 

3. 회원 가입을 위한 API 생성

 

 

아래의 경로에 파일을 생성한다

 

account/serializers.py

 

from .models import User
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

    def create(self, validated_data):
        email = validated_data.get('email')
        password = validated_data.get('password')
        custom_field = validated_data.get('custom_field')
        user = User(
            email = email,
            custom_field=custom_field,
        )
        user.set_password(password)
        user.save()
        return user

 

 

 

 

4. view  파일 수정

 

account/views.py

 

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from django.contrib.auth import authenticate
from django.db.models import Q

from .serializers import UserSerializer

from account.models import User

class RegisterAPIView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()

            token = TokenObtainPairSerializer.get_token(user)
            refresh_token = str(token)
            access_token = str(token.access_token)
            res = Response(
                {
                    "user": serializer.data,
                    "message": "register successs",
                    "token": {
                        "access": access_token,
                        "refresh": refresh_token,
                    },
                },
                status=status.HTTP_200_OK,
            )

            return res
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class AuthView(APIView):

    def post(self, request):
        _email    = request.data.get("email")
        _password = request.data.get("password")

        if _email is None or _password is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)
            
        user = authenticate(email=_email, password=_password)
        
        if user is not None:
            serializer = UserSerializer(user)
            token = TokenObtainPairSerializer.get_token(user)
            refresh_token = str(token)
            access_token = str(token.access_token)
            res = Response(
                {
                    "user": serializer.data,
                    "message": "login success",
                    "token": {
                        "access": access_token,
                        "refresh": refresh_token,
                    },
                },
                status=status.HTTP_200_OK,
            )
            return res
        else:
            user = User.objects.all().filter( Q(email__icontains=_email) )
            
            
            if user:
                return Response({"실패": "비밀번호가 일치하지 않습니다."}, status=status.HTTP_401_UNAUTHORIZED)
            
            if user.count() == 0:
                return Response({"실패": "회원 정보가 존재하지 않습니다."}, status=status.HTTP_404_NOT_FOUND)

            return Response(status=status.HTTP_400_BAD_REQUEST)

 

 

 

 

 

 

5. config/urls.py 에 유저 주소 추가

 

from django.contrib import admin
from django.urls import path

from account.views import RegisterAPIView, AuthView

from rest_framework_simplejwt.views import ( TokenObtainPairView, TokenRefreshView, TokenVerifyView)

urlpatterns = [
    path('admin', admin.site.urls),
    
    path("api/sign-in", AuthView.as_view()), #로그인
    path("api/sign-up", RegisterAPIView.as_view()), #회원가입하기

    path('api-jwt-auth/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/jwt/refresh', TokenRefreshView.as_view(), name='token_refresh'),
    path('api/jwt/verify', TokenVerifyView.as_view(), name='token_verify'),
]

 

자 이제 손쉽게 회원 가입 & 인증 로직이 완성 되었다.

로그인을 하면 엑세스 토큰을 넘겨받는데 해당 토큰을 가지고 다른 로직을 구현하면 된다.

 

 

 

 

 

 

여기까지 따라왔다면 폴더 구조가 아래와 같다