Django 인증: 듀얼 경로 여정
Grace Collins
Solutions Engineer · Leapcell

소개
웹 개발의 세계에서 사용자 인증은 거의 모든 애플리케이션에 있어 필수적인 기능입니다. 간단한 블로그부터 복잡한 전자 상거래 플랫폼까지, 사용자 액세스, 역할 및 프로필을 안전하게 관리하는 것이 가장 중요합니다. "마감 기한이 있는 완벽주의자를 위한 웹 프레임워크"인 Django는 즉시 사용할 수 있는 매우 강력하고 유연한 인증 시스템을 제공합니다. 그러나 애플리케이션이 복잡해지고 고유한 요구 사항이 나타남에 따라 개발자는 중요한 결정에 직면하게 됩니다: Django의 내장 User
모델을 고수해야 할까요, 아니면 자신의 요구에 더 잘 맞도록 사용자 지정 사용자 모델의 영역으로 모험을 떠나야 할까요? 이 글은 두 가지 접근 방식의 뉘앙스를 파헤치며, Django 애플리케이션을 설계할 때 정보에 입각한 결정을 내리는 데 도움이 되는 포괄적인 가이드를 제공합니다.
Django 인증의 핵심 개념
비교 분석에 들어가기 전에 Django의 인증 시스템과 관련된 핵심 구성 요소에 대한 공통된 이해를 확립해 보겠습니다.
User
모델: 이것은 애플리케이션의 개별 사용자를 나타내는 중심 조각입니다. 사용자 이름과 비밀번호 해시와 같은 자격 증명 및 기본 식별 정보를 저장합니다.- 인증 백엔드: 데이터베이스와 비밀번호를 확인하는 등 실제 인증 프로세스를 처리하는 클래스입니다. Django에는
User
모델에 대해 인증하는 기본 백엔드가 포함되어 있습니다. AUTH_USER_MODEL
설정: 애플리케이션의 사용자 모델로 사용할 모델을 지정하는 중요한 Django 설정입니다. 기본적으로auth.User
로 설정됩니다.- 권한 및 그룹: Django의 인증 시스템은 권한 관리로도 확장되어 권한(예: "게시물 편집 가능")을 정의하고 사용자에게 역할(예: "편집자")을 할당하여 액세스 제어를 관리할 수 있습니다.
이제 Django에서 사용자를 관리하는 두 가지 주요 경로를 살펴보겠습니다.
Django의 내장 인증 시스템
Django의 기본 사용자 모델인 django.contrib.auth.models.User
는 대부분의 Django 프로젝트에 사전 구성된 강력하고 잘 테스트된 솔루션입니다. 즉시 사용 가능하고 포괄적인 기능 세트로 인해 많은 애플리케이션에 대한 최상의 시작점인 경우가 많습니다.
기능 및 장점
- 즉시 사용 가능: 설정이 필요 없습니다. 슈퍼유저를 만들고 인증을 시작하기만 하면 됩니다.
- 강력하고 안전함: 수년간의 커뮤니티 검토, 버그 수정 및 보안 강화의 혜택을 누릴 수 있습니다. 비밀번호 해싱, 살팅, 세션 관리 등을 처리합니다.
- 관리 통합: Django 관리 인터페이스와 원활하게 통합되어 관리자가 최소한의 노력으로 사용자 및 그룹을 관리할 수 있습니다.
- 포괄적인 기능:
username
,password
,email
,first_name
,last_name
,is_staff
,is_active
,is_superuser
,last_login
,date_joined
필드가 포함됩니다. - 비밀번호 재설정 기능: Django는 처음부터 사용자가 직접 올바르고 안전하게 구현하기 복잡한 비밀번호 재설정을 처리하는 데 필요한 보기와 양식을 제공합니다.
언제 사용해야 하는가
내장 User
모델은 다음과 같은 경우에 훌륭한 선택입니다.
- 대부분의 표준 웹 애플리케이션: 사용자 요구 사항이 기본적으로 제공되는 필드와 일치하는 경우.
- 빠른 프로토타이핑: 인증 시스템을 신속하게 구축합니다.
- 사용자 프로필이 최소화된 애플리케이션:
User
모델에 대한 1:1 관계(예:UserProfile
모델)를 통해 추가 사용자 데이터가 처리되는 경우.
예시: 내장 사용자 사용
Post
를 작성자와 연결한다고 가정해 보겠습니다. 내장 User
모델을 사용하면 간단합니다.
# myapp/models.py from django.db import models from django.contrib.auth.models import User # 내장 User 가져오기 class Post(models.Model): title = models.CharField(max_length=200) content = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE) # 직접 외래 키 created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title # Django 보기 또는 셸에서 사용 예시: # from django.contrib.auth.models import User # from myapp.models import Post # # user = User.objects.create_user(username='john_doe', password='securepassword') # post = Post.objects.create(title='My First Post', content='Hello, world!', author=user)
사용자 지정 사용자 모델
내장 User
모델은 강력하지만 항상 모든 요구 사항에 부합하지는 않을 수 있습니다. 종종 애플리케이션은 더 구체적인 사용자 관련 데이터(예: phone_number
, date_of_birth
, user_type
, avatar
)가 필요하거나 다른 인증 식별자(예: 사용자 이름 대신 이메일)를 선호할 수 있습니다. 이곳에서 사용자 지정 사용자 모델이 빛을 발합니다. Django는 AbstractUser
또는 AbstractBaseUser
를 확장하여 사용자 모델을 사용자 지정하는 두 가지 주요 방법을 제공합니다.
AbstractUser
AbstractUser
는 AbstractBaseUser
를 서브클래스하고 username
, email
, first_name
, last_name
, is_staff
, is_active
, is_superuser
, last_login
, date_joined
를 포함한 전체 User
모델의 구현을 제공합니다. 필요한 추가 필드, 메서드 또는 관리자를 추가할 수 있습니다. Django의 표준 사용자 필드를 유지하고 싶다면 대부분의 사용자 지정 사용자 모델에 권장되는 접근 방식입니다.
AbstractBaseUser
AbstractBaseUser
는 비밀번호 해싱 및 토큰화된 비밀번호 재설정을 포함하여 사용자 모델의 핵심 구현을 제공합니다. 다른 필드는 포함하지 않습니다. 이를 사용하는 경우 사용자 모델에 필요한 모든 필드(예: 사용자 이름 대신 email
)를 어떻게 식별하는지를 포함하여 정의해야 합니다. 또한 REQUIRED_FIELDS
및 USERNAME_FIELD
를 정의해야 합니다. 이 접근 방식은 최대의 유연성을 제공하지만 더 많은 작업이 필요합니다.
사용자 지정 사용자 모델은 언제 사용해야 하는가
- 고유한 사용자 필드 추가: 사용자 지정 사용자 컨트롤러에서 제공되지 않는 추가 사용자 속성이 필요한 경우(예:
phone_number
,date_of_birth
,company_id
). - 인증 식별자 변경: 사용자 이름 대신 이메일 주소를 사용하여 사용자가 로그인하도록 하려는 경우.
- 핵심 사용자 동작 변경: 사용자가 관리, 생성 또는 식별되는 방식을 많이 사용자 지정해야 하는 경우.
- 1:1 프로필 모델 회피:
User
에 연결된UserProfile
모델을 만드는 대신 모든 사용자 데이터를 사용자 지정 사용자 모델에 직접 넣을 수 있습니다.
예시: AbstractUser
확장
이메일로 인증하고 phone_number
필드를 포함하는 사용자 지정 사용자 모델을 만들어 보겠습니다.
# myapp/models.py from django.contrib.auth.models import AbstractUser from django.db import models class CustomUser(AbstractUser): # 추가 필드를 여기에 추가하세요 phone_number = models.CharField(max_length=15, blank=True, null=True) # email은 AbstractUser에서 이미 제공되지만 USERNAME_FIELD로 만들고 싶습니다. # 또한 email은 고유해야 합니다. email = models.EmailField(unique=True) # 이메일 필드를 인증에 사용하도록 Django에 알립니다. USERNAME_FIELD = 'email' # REQUIRED_FIELDS는 createsuperuser를 통해 사용자를 만들 때 묻는 항목입니다. # 이 필드는 USERNAME_FIELD 및 비밀번호 외에 존재해야 합니다. # USERNAME_FIELD 또는 비밀번호를 여기에 나열하지 않도록 하세요. REQUIRED_FIELDS = ['username'] # 사용자 이름도 수집하기를 원합니다. def __str__(self): return self.email # settings.py에서 사용자 지정 사용자 모델을 반드시 지정해야 합니다: # AUTH_USER_MODEL = 'myapp.CustomUser'
중요 참고 사항: AUTH_USER_MODEL
설정은 프로젝트에 대해 첫 번째 마이그레이션을 실행하기 전에 (즉, python manage.py migrate
를 실행하기 전에) 설정되어야 합니다. 기본 auth.User
로 초기 마이그레이션을 실행한 후 사용자 지정 사용자 모델로 전환하기로 결정했다면, 이는 훨씬 더 복잡한 프로세스이며 일반적으로 신중한 데이터 마이그레이션 또는 새로 시작이 필요합니다. 이 때문에 프로젝트 수명 주기 초기에 사용자 모델을 결정하는 것이 중요합니다.
예시: AbstractBaseUser
확장
이 접근 방식은 사용자 모델을 거의 처음부터 구축하여 완전한 제어권을 원하는 경우를 위한 것입니다.
# myapp/models.py from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager from django.db import models from django.utils import timezone class CustomUserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): if not email: raise ValueError('The Email field must be set') email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) extra_fields.setdefault('is_active', True) if extra_fields.get('is_staff') is not True: raise ValueError('Superuser must have is_staff=True.') if extra_fields.get('is_superuser') is not True: raise ValueError('Superuser must have is_superuser=True.') return self.create_user(email, password, **extra_fields) class MinimalUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True) first_name = models.CharField(max_length=30, blank=True) last_name = models.CharField(max_length=30, blank=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) date_joined = models.DateTimeField(default=timezone.now) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['first_name', 'last_name'] objects = CustomUserManager() def __str__(self): return self.email def get_full_name(self): return f"{self.first_name} {self.last_name}".strip() def get_short_name(self): return self.first_name # settings.py에서: # AUTH_USER_MODEL = 'myapp.MinimalUser'
이 MinimalUser
예시에서는 다음을 수행해야 했습니다.
- 모든 기본 필드(
email
,first_name
,last_name
,is_active
,is_staff
,date_joined
)를 정의했습니다. is_superuser
,groups
,user_permissions
필드를 얻기 위해PermissionsMixin
에서 상속했습니다.USERNAME_FIELD
를'email'
로 정의했습니다.createsuperuser
에 대한REQUIRED_FIELDS
를 정의했습니다.- 이메일 정규화를 포함하여 사용자 및 슈퍼유저 생성을 처리하는 사용자 지정
UserManager
(CustomUserManager
)를 만들었습니다.
보시다시피 이 작업은 상당한 양의 보일러플레이트가 필요하지만 사용자 모델의 스키마 및 생성 프로세스에 대한 완전한 제어를 제공합니다.
사용자 모델 간 마이그레이션
초기 마이그레이션 이후 AUTH_USER_MODEL
을 변경하는 것이 간단한 작업이 아님이 강조되어야 합니다. 기본 User
로 시작했다가 나중에 사용자 지정 모델이 필요하다고 결정하면 상당한 어려움에 직면하게 됩니다. 일반적으로 다음이 필요합니다.
- 사용자 지정 사용자 모델을 만듭니다.
- 이전
auth.User
테이블에서 새 사용자 지정 사용자 모델 테이블로 데이터를 마이그레이션하는 마이그레이션 파일을 수동으로 만듭니다. auth.User
를 가리키는 모든 외래 키를 사용자 지정AUTH_USER_MODEL
을 가리키도록 신중하게 업데이트합니다.- 모든 참조가 업데이트되었는지 확인하면 모든
auth
앱 마이그레이션과 잠재적으로auth_user
테이블을 제거합니다.
이 프로세스는 세심하게 실행되지 않으면 오류와 데이터 손실이 발생하기 쉽습니다. 따라서 항상 프로젝트 시작 시점에 사용자 모델을 결정하는 것이 좋습니다. 심지어 첫 번째 makemigrations
및 migrate
명령을 실행하기 전입니다.
결론
Django의 내장 User
모델과 사용자 지정 사용자 모델은 각각 고유한 이점과 사용 사례를 가진 강력한 솔루션을 제공합니다. 내장 모델은 표준 사용자 요구 사항을 가진 애플리케이션에 대한 안전하고 효율적이며 즉시 사용 가능한 옵션을 제공하여 즉각적인 개발과 강력한 보안을 즉시 사용할 수 있습니다. 애플리케이션에 고유한 사용자 속성, 사용자 지정 인증 식별자(예: 이메일 기반 로그인) 또는 사용자 관리에 대한 보다 세분화된 제어가 필요한 경우 사용자 지정 사용자 모델(가급적 AbstractUser
를 확장하여)을 구현하는 것이 더 나은 선택이 됩니다. 이 결정은 이상적으로 프로젝트 시작 시점에 내려지며 사용자 관리 시스템의 유연성과 확장성을 결정합니다. 궁극적으로 올바른 선택은 사용자에게 완벽하게 맞는 안전하고 적응 가능하며 Django 애플리케이션을 구축할 수 있도록 합니다.