유저에 대한 비밀번호를 암호화하지 않고 관리하고 싶을 경우
-> 비밀번호를 암호화 하지않는User
모델 작성 후
->django.contrib.auth.authenticate
를 커스텀하여 로그인 기능 구현하기
AbstractBaseUser
상속
(AbstractBaseUser vs AbstractUser 비교하기)set_password
없이UserManager
작성# 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
- 적당한 곳에 작성
# 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' ]
- 로그인 기능 작성
# 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 출력 결과
구현코드
참고