취미삼아 배우는 프로그래밍

Django REST Framework - Authentication(인증, 로그인, 뷰) 본문

파이썬(장고)

Django REST Framework - Authentication(인증, 로그인, 뷰)

Nadure 2020. 7. 17. 04:29

동영상및 제 코드를 보고나서 정리하는 글입니다.

 

UserModel은 원본 상태인 걸로 예를 들겁니다.

인증 방식은 Token인증, 테스트 툴은 httpie로 진행합니다.

httpie.org/docs#installation

 

HTTPie 2.2.0 (latest) documentation

CLI HTTP that will make you smile. JSON and sessions support, syntax highlighting, wget-like downloads, plugins, and more.

httpie.org

 

 

1. 설정 추가

# Settings.py

# ...
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}
# ...

INSTALLED_APPS = [
	# ...
    'rest_framework.authtoken', # 추가
]

# ...

 

python manage.py makemigrations

python manage.py migrate

token이 생성됨

 

2. 회원가입

1) Serializer

from django.contrib.auth.models import User
from rest_framework import serializers


class RegistrationUserSerializer(serializers.ModelSerializer):
    """
    ModelSerializer로 만든다.
    """
    
    # password2는 따로 없기 때문에 추가로 만들어 주어야 한다.
    password2 = serializers.CharField(style={'input_type':'password'}, write_only=True)

    class Meta:
        """
        메타 클래스에 필드, 모델 등을 설정하고 
        password 필드의 스타일을 정해준다.
        """
        model = User
        fields = ['username', 'email', 'password','password2']
        extra_kwargs = {
            'password' : {'write_only':True}
        }
    
    def save(self):
        """
        저장시 한 번 더 확인한다.
        """
        account = User(
            email = self.validated_data['email'],
            username = self.validated_data['username']
        )

        password = self.validated_data['password']
        password2 = self.validated_data['password2']

        if password != password2:
            raise serializers.ValidationError({'password':'Passwords must match'})
        account.set_password(password)
        account.save()
        return account

 

 

2) View

# 아까 만든 RegistrationUserSerializer 임포트
from rest_framework.authtoken.models import Token
from rest_framework import permissions
from rest_framework.decorators import api_view

@api_view(['POST',])
# 나의 경우에 Permission class가 없다고 안되서 넣어줬다.
@permission_classes((permissions.AllowAny, )) 
def registration_view(request):
    if request.method == 'POST':
        serializer = RegistrationUserSerializer(data=request.data)
        data = {}
        if serializer.is_valid():
            account =serializer.save()
            data['response'] = "successfully registred a new user"
            data['email'] = account.email
            data['username'] = account.username
            token = Token.objects.get(user=account).key
            data['token'] = token

        else:
            data = serializer.errors
        return Response(data)

 

3) URL 등록

urlpatterns = [
	# ...
    path('api/auth/register/', registration_view, name='registerUser'),
    # ...
]

테스트

http POST http://127.0.0.1:8000/api/auth/register/ username=apdulano2 password=password password2=password email=nnnnadure@nadure.com

굳.

 

3. 로그인

로그인은 간단합니다.

뷰는 따로 필요없고 임포트해서 주소만 할당하면 끝

from rest_framework.authtoken.views import obtain_auth_token


urlpatterns = [
	# ...
    path('api/auth/register/', registration_view, name='registerUser'),
    path('api/auth/login/', obtain_auth_token, name='login'),
    # ...
]

테스트 스샷

http POST http://127.0.0.1:8000/api/auth/login/ username=apdulano password=password

간단히 토큰을 얻을 수 있습니다.

그러면 이 토큰을 뷰에 접몹시켜보겠습니다.

 

4. 뷰에 접목

간단히 리퀘스트 유저가 누구인지를 알려주는 뷰를 만들었습니다.

from rest_framework.response import Response

def example_view(request, format=None):
    content = {
        'user': str(request.user),
        # 'auth': request.token
    }
    return Response(content)

 

URL을 설정해준 뒤,

urlpatterns = [
	# ...
	path('test/', example_view, name='test' ),
    # ...
]

 

 

뷰에 api_view로 등록하는 데코레이터 및 인증된 사람만을 걸러주는 데코레이터를 해줍니다.

from rest_framework.decorators import api_view, permission_classes, authentication_classes

@api_view(['GET',])
# @authentication_classes([SessionAuthentication, BasicAuthentication])
@permission_classes((IsAuthenticated, ))
def example_view(request, format=None):
    content = {
        'user': str(request.user),
        # 'auth': request.token
    }
    return Response(content)

이러면 isAuthenticated에서는 세팅해두었던 인증을 참조해서 인증됐는지 확인하고 패스합니다.

 

이전에 로그인 하면 토큰을 줬었는데,

토큰을 넣고 페이지를 GET 해봅니다.

http GET http://127.0.0.1:8000/test/ "Authorization: Token  d91cf5cf0dd85a61bb18763f8279dbb75f0a09dc"

 

잘 되는군요

그리고 다른 유저의 토큰을 줘봅니다.

굿잡.

 

토큰 값에 따라 인증된 request.user가 다르게 나오는 것을 알 수 있습니다.

 

Comments