[Django] 세상에서 제일 쉽고 빠른 토큰 방식의 인증 구현하기
articles/serializers.py
외부키로 연결된 user를 채우기 위해
accounts/serializers.py
를 가져온다.완전히 DB에 저장되기 전에 not null constraint를 방지하기 위해
required=False
인자를 채워준다.
from rest_framework import serializers
from .models import Article
from accounts.serializers import UserSerializer
class ArticleListSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'title','content' ,'created_at']
class ArticleSerializer(serializers.ModelSerializer):
user = UserSerializer(required=False) # is_valid() 에서 유무검증 pass
class Meta:
model = Article
fields = '__all__'
articles/views.py
@permission_classes
&IsAuthenticated
: 로그인을 한 사용자만이 API POST 요청을 통해 새 아티클을 작성할 수 있게 한다.NOT NULL CONSTRAINT 방지를 위해 최종 저장하는 과정에서 user를 넣어준다.
from django.shortcuts import get_object_or_404
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from .serializers import ArticleListSerializer, ArticleSerializer
from .models import Article
@api_view(['GET'])
def article_list(request):
articles = Article.objects.all()
serializer = ArticleListSerializer(articles, many=True)
return Response(serializer.data)
@api_view(['GET'])
def article_detail(request, article_pk):
article = get_object_or_404(Article, pk=article_pk)
serializer = ArticleSerializer(article)
return Response(serializer.data)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_article(request):
serializer = ArticleSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save(user=request.user) # NOT NULL CONSTRAINT FAILED
return Response(serializer.data)
settings.py
- 토큰 인증 방식의 회원가입 및 로그인 방식의 구현을 용이하게 하는 패키지 2개를 추가 설치한다.
$ pip install django-rest-auth
$ pip install django-allauth
- 다음과 같이 앱을 등록해 준 뒤 토큰 인증 방식을 위한 설정을 다음과 같이 진행한다.
INSTALLED_APPS = [
# registration
'django.contrib.sites',
# DRF
'rest_framework',
'rest_framework.authtoken',
# rest_auth + allauth
'rest_auth',
'allauth',
'allauth.account',
'rest_auth.registration',
# My Apps
'accounts',
'articles',
]
# django sites app setting
SITE_ID = 1
# DRF auth settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
}
- 마지막으로 마이그레이션을 진행한다.
$ python manage.py migrate
urls.py
Rest-auth 가 제공하는 로그인, 회원가입 페이지로 연결하기 위해 다음과 같이 url을 정의한다.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/', include('articles.urls')),
# rest-auth
path('rest-auth/', include('rest_auth.urls')),
path('rest-auth/signup/', include('rest_auth.registration.urls')),
]
포스트맨을 활용한 API 요청 보내기
- 로그인 시도하기
POST 요청을 통해 아이디와 비밀번호를 json으로 보내면 토큰을 자동으로 생성해 준다.
로그인 시 고유한 토큰 생성은 사실 복잡한 로직이 있지만 패키지를 통해 간단하게 구현할 수 있었다.
- 로그인을 바탕으로 새글 쓰기
앞서
views.py
에서 정의한 대로 로그인을 하지 않으면 새 아티클을 작성할 수 없다.@permission_classes([IsAuthenticated])
따라서 앞서 로그인을 통해 만들어진 토큰을 넘겨줌으로써 해당 사용자가 인증된(Authenticated) 유저인지 검증하는 과정이 필요하다. 하지만 이 역시 상당부분 구현되어 있으므로 어려울 것이 없다.
헤더 정보에 사진과 같이 {"KEY":"Authorization", "VALUE": "Token <token>"}
형식으로 넣어주어야 한다. 넣어주지 않으면 보내고지 하는 API 요청이 인증받은 사용자가 보낸 것인지 알 방도가 없기 때문에 ` “detail”: “Authentication credentials were not provided.”` 와 같은 401 에러를 출력한다.
포스트맨은 헤더에 토큰 정보를 넣어 POST 요청을 보내는 일 조차 쉽게 해주는 좋은 어플이다.
- 새 글 확인하기
GET 요청을 통해 방금 쓴 글을 확인할 수 있다. 사실 토큰 방식의 인증 방식을 구현하기 위해서는 로그인에 성공하면 personal한 토큰을 생성하고 이를 저장하고 헤더에 붙이는 등의 구현 과정이 필요하지만 라이브러리를 통해 쉽게 구현할 수 있었다.
댓글남기기