[221227 - TIL] Django Authentication Customizing

Dongwoo Kim·2022년 12월 27일
0

TIL / WIL

목록 보기
63/113

1. 시나리오 예시

유저에 대한 비밀번호를 암호화하지 않고 관리하고 싶을 경우
-> 비밀번호를 암호화 하지않는 User 모델 작성 후
-> django.contrib.auth.authenticate를 커스텀하여 로그인 기능 구현하기

2. User Model

# user.models.py

from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

class UserManager(BaseUserManager):
    def create_user(self, username, password=None):
        if not username:
            raise ValueError('Users must have an username')
        user = self.model(
            username=username,
        )
        # user.set_password(password)
        user.password = password
        user.save(using=self._db)
        return user

    def create_superuser(self, username, password=None):
        user =  self.create_user(
            username=username,
        ) 
        # user.set_password(password)
        user.password = password
        user.is_admin = True
        user.save(using=self._db)
        return user

class User(AbstractBaseUser):

    username = models.CharField("사용자", max_length=24, unique=True)
    password = models.CharField("비밀번호", max_length=128)
 
    def __str__(self):
        return f"{self.id} {self.username}"

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    USERNAME_FIELD = 'username'

    objects = UserManager()

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.is_admin

3. auth.authenticate customizing

  • 적당한 곳에 작성
# user.custom_auth.py

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User as UserModel

class CustomBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None):
        try:
            user = UserModel.objects.get(username=username, password=password)
        except UserModel.DoesNotExist:
           return None
        return user

    def get_user(self, user_id):
        try:
            return UserModel.objects.get(pk=user_id)
        except UserModel.DoesNotExist:
            return None
  • settings.py에 CustomBackend을 먼저 사용할 것을 설정
# settings.py

...
AUTH_USER_MODEL = "user.User"

AUTHENTICATION_BACKENDS = [
    'user.custom_auth.CustomBackend',
    'django.contrib.auth.backends.ModelBackend'
]

4. 커스텀한 authenticate를 이용한 로그인 해보기

  • 로그인 기능 작성
# user.views.py

from django.contrib import auth

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

class UserView(APIView):
    def post(self, request):
        user = auth.authenticate(request, **request.data)
        if not user:
            return Response({"message": "로그인에 실패했습니다."}, status=status.HTTP_400_BAD_REQUEST)

        auth.login(request, user)
        return Response({"message": "로그인에 성공했습니다."}, status=status.HTTP_200_OK)
  • 테스트 코드 작성
# user.tests.py

from django.urls import reverse
from rest_framework.test import APITestCase
from user.models import User as UserModel

class UserViewTest(APITestCase):
    def setUp(self):
        user_data = {
            "username": "kimphysicsman",
            "password": "4885"
        }
        UserModel.objects.create_user(**user_data)

    def test_sign_in_user(self):
        sing_in_data = {
            "username": "kimphysicsman",
            "password": "4885"
        }

        response = self.client.post(
            reverse("user"),
            sing_in_data,
            format="json"
        )

        print(response.data)
  • test 및 response.data 출력 결과



구현코드


https://github.com/kimphysicsman/TIL-221227


참고


profile
kimphysicsman

0개의 댓글