[Django] 세상에서 제일 쉽고 빠른 토큰 방식의 인증 구현하기

유나니·2020년 10월 10일
0

python_til

목록 보기
1/2

articles/serializers.py

  1. 외부키로 연결된 user를 채우기 위해 accounts/serializers.py 를 가져온다.

  2. 완전히 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

  1. @permission_classes & IsAuthenticated : 로그인을 한 사용자만이 API POST 요청을 통해 새 아티클을 작성할 수 있게 한다.

  2. 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

  1. 토큰 인증 방식의 회원가입 및 로그인 방식의 구현을 용이하게 하는 패키지 2개를 추가 설치한다.
$ pip install django-rest-auth
$ pip install django-allauth
  1. 다음과 같이 앱을 등록해 준 뒤 토큰 인증 방식을 위한 설정을 다음과 같이 진행한다.
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',
    ]
}
  1. 마지막으로 마이그레이션을 진행한다.
$ 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 요청 보내기

  1. 로그인 시도하기

POST 요청을 통해 아이디와 비밀번호를 json으로 보내면 토큰을 자동으로 생성해 준다.

로그인 시 고유한 토큰 생성은 사실 복잡한 로직이 있지만 패키지를 통해 간단하게 구현할 수 있었다.

  1. 로그인을 바탕으로 새글 쓰기

앞서 views.py에서 정의한 대로 로그인을 하지 않으면 새 아티클을 작성할 수 없다. @permission_classes([IsAuthenticated])

따라서 앞서 로그인을 통해 만들어진 토큰을 넘겨줌으로써 해당 사용자가 인증된(Authenticated) 유저인지 검증하는 과정이 필요하다. 하지만 이 역시 상당부분 구현되어 있으므로 어려울 것이 없다.

헤더 정보에 사진과 같이 {"KEY":"Authorization", "VALUE": "Token <token>"} 형식으로 넣어주어야 한다. 넣어주지 않으면 보내고지 하는 API 요청이 인증받은 사용자가 보낸 것인지 알 방도가 없기 때문에 "detail": "Authentication credentials were not provided." 와 같은 401 에러를 출력한다.

포스트맨은 헤더에 토큰 정보를 넣어 POST 요청을 보내는 일 조차 쉽게 해주는 좋은 어플이다.

  1. 새 글 확인하기

GET 요청을 통해 방금 쓴 글을 확인할 수 있다. 사실 토큰 방식의 인증 방식을 구현하기 위해서는 로그인에 성공하면 personal한 토큰을 생성하고 이를 저장하고 헤더에 붙이는 등의 구현 과정이 필요하지만 라이브러리를 통해 쉽게 구현할 수 있었다.

profile
User First, Mobile Friendly

0개의 댓글