DRF(Django Rest Framework) and Vue.js

Ryan Kim
10 min readAug 3, 2019

--

part 2. JWT 토큰 발급 및 url api 설정하기

Likelion 7th (해당 이미지 사용이 저작권 침해시, 삭제하겠습니다.)

part 1의 글에서 settings.py 및 DB 설정이 끝났다. 오늘은 url api 설정과 JWT 토큰이 정상발급 되는지 확인해보자.

user/models.pyfrom django.db import models #Django default settingfrom django.contrib.auth.models import AbstractUser #장고에서 제공하는 사용자 모델을 그대로 가져와 사용하자.
class CustomUser(AbstractUser): def __str__(self): return self.username

나는 장고에서 제공하는 auth.models에서 AbstracUser 모델을 가져와 그대로 사용했다. 사용자 model 관련 정보를 커스터마이징 할 사람이 아니라면 편리하다.

api folder 만들기

이제 user 폴더 내에 api 폴더를 만들어서 serializers.py, urls.py, views.py를 만들자.

각각의 기능들은 코드를 작성하면서 설명하겠다. 우선 좀 전에 models.py 에 작성한 내용을 migration을 다시 해줘야한다.

#migration은 절대 잊지 말자!! (python manage.py runserve하면 어차피 잊고 싶어도 잊지 않게 되지만)python manage.py makemigrationspyhton manage.py migrate
user/api/serializers.py

serializers.py를 형성하면 파일이 당연히 아무것도 작성 안된 빈 파일이 있을 것이다. 거기에 위의 사진과 같은 코드를 작성하자. 코드 작성하기 귀찮은 사람들을 위해 친절하게 Control + C 코드를 넣어준다.

#user/api/serializer.pyfrom rest_framework import serializersfrom user.models import CustomUser
class UserDisplaySerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ["username"]

Srializer는 한국어로 직역하면 ‘직렬화’라는 것을 도와주는 파일이다. 기본 Django만 사용하면 Serializer를 사용할 일이 거의 없는데, 쉽게 말해 우리가 models.py에 생성한 자료들을 JSON 형태로 바꿔주는 작업을 해주는 파일이다. 그래서 우리가 계정을 관리하는 user 폴더의 models를 import하고, 좀 전에 작성했던 CustomUser 모델을 가져와 Serialize한다 생각하면 된다. 왜 이름이 Serialize인지는 이후에 스크린샷을 통해 보여주겠다.

user/api/views.py
#user/api/views.pyfrom rest_framework.response import Responsefrom rest_framework.views import APIViewfrom user.api.serializers import UserDisplaySerializerclass CurrentUserAPIView(APIView): def get(self, request):  serializer = UserDisplaySerializer(request.user)  return Response(serializer.data)

우리가 DRF가 아닌 Django를 사용하던 시절을 떠올려보자. models.py 를 생성하면 그 다음에 forms.py라는 파일을 형성하여

#forms.py 예시 (여기서는 불필요한 코드다)from django_registration.forms import RegistrationFormfrom users.models import CustomUserclass CustomUserForm(RegistrationForm):  class Meta(RegistrationForm.Meta):   model = CustomUser

이런 형태로 form을 만들어줘 이후에 views.py를 만들었을 것이다. 그리고 .html에 {{form.as_p}} 뭐 이런 형태로 코드를 작성했던 기억이 있을 것이다. 그 작업에서 forms.py를 serializers.py로 대체하여 views.py에 사용한다 보면 된다.

잘 기억해야 될 것은 Client에서 서버에 요청하는 정보는 기본적으로 JSON 형태며 서버는 response 형태를 serializer의 data를 보내주는 형태를 취한다.

여기서 한 가지 참고할 점은 APIView의 존재다. 해당 모듈의 내부를 까보면,

APIView의 내부 코드

대충 이런 형태를 띄는데, 우리가 기존에 views.py를 작성할 때를 생각해보면

...orm = CustomUser.object.all()
form.save()
...

이런 형태로 ORM부터 쿼리로 형성하고 form.save(), 그리고 return render 머시기 형태로 쭉 쓰는데 이런 불필요한 작업을 할 필요를 줄여준다. 단지, 마지막에 작성된 것은 response 뿐이다.

user/api/urls.py

마지막으로 api의 url을 호출하는 코드를 쓰자.

from django.urls import pathfrom user.api.views import CurrentUserAPIViewurlpatterns = [path("user/", CurrentUserAPIView.as_view(), name="current-user")]

가끔 혼동하는 경우가 있는데, views.CurrentUserAPIView인지 아님 CurrentUserAPIView.as_view()를 사용하는 것인지 헷갈릴텐데 views.py에서 CurrentUserAPIView가 def형태로 선언되었다면 views.CurrentUserAPIView를 사용하고 class형태로 선언되었다면 CurrentUserAPIView.as_view() 사용한다.

거의 다 끝났다. 이제 spa 폴더에서 urls.py로 넘어가자.

spa/urls.py
from django.contrib import adminfrom django.urls import path, includefrom rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_tokenurlpatterns = [path('admin/', admin.site.urls),#user.api의 모든 url 정보를 받아오는 path 설정 (include)
path("api/", include("user.api.urls")),
path("api-auth/", include("rest_framework.urls")),#login, registration등 path 설정
path("api/rest-auth/", include("rest_auth.urls")),
# 토큰 발급 및 재발급 페이지 설정
path('api/rest-auth/obtain_token/', obtain_jwt_token, name="obtain-jwt"),
path('api/rest-auth/refresh_token/', refresh_jwt_token, name="refresh-jwt"),path("api/rest-auth/registration/", include("rest_auth.registration.urls")),]

위의 경로들을 추가하자. 기본적으로 part 1에서 추가했던 모듈들의 경로 (JWT, rest-auth 등)들인데 토큰 발급과 로그인, 회원가입을 처리하기 위해 작성했다. 그리고 서버를 돌린다.

python manage.py runserver

로그인은 http://localhost:8000/api/rest-auth/login 페이지로, 그리고 회원가입은 http://localhost:8000/api/rest-auth/registration 으로 접속하자.

Login 정보
http://localhost:8000/api/rest-auth/obtain_token/
http://localhost:8000/api/rest-auth/refresh_token/

JWT로 토큰 발급 및 재발급이 정상작동하고, 로그인 했을 때 토큰 정보가 함께 발급되면 백엔드에서 로그인, 회원가입 관련 모든 작업이 정상적으로 마무리 된 것이다. 그리고 앞 부분에서 설명하다 말았던 부분이 JSON형태 데이터 출력인데, 위의 페이지가 JSON 형태 데이터 출력이다. 화면이 정상적으로 위와 같이 나온다면 백엔드에서 작업을 잘 마무리 한 것이다.

{"token" : "머시기머시기"
}

part 3, part 4에서는 드디어 백엔드 작업이 끝났으니 Vue.js로 넘어가서 로그인, 회원가입 하는 기능들을 추가해 나가고자 한다. 사실 로그인 기능만 2주 넘게 삽질 했었는데(JS 유저가 아니어서 JS 공부하며 Vue.js 코드를 작성했다.) 막상 해보니 별 거 없다. 곧 part 3, 4 내용으로 돌아오겠다.

part 1, part 3, part 4, part 5 글 링크

--

--