Django Auth 모듈을 활용한 사용자 인증 시스템 구축 및 커스텀 유저 모델 확장

Django 인증 시스템(Auth 모듈) 개요

웹 애플리케이션을 개발할 때 사용자 등록, 로그인, 세션 관리, 비밀번호 재설정 등의 인증 로직을 매번 직접 구현하는 것은 비효율적입니다. Django는 이러한 반복적인 작업을 해소하기 위해 강력한 내장 인증 시스템인 django.contrib.auth 모듈을 제공합니다. 이 모듈은 기본적으로 auth_user 테이블을 사용하여 사용자 데이터를 관리하며, 보안성이 검증된 해싱 알고리즘과 세션 관리 메커니즘을 내장하고 있습니다.

주요 인증 함수 및 메서드 활용

Auth 모듈은 사용자 인증 및 세션 관리를 위한 다양한 유틸리티 함수를 제공합니다.

authenticate() 및 login()

authenticate() 함수는 전달된 자격 증명(일반적으로 아이디와 비밀번호)을 검증합니다. 검증에 성공하면 백엔드 인증 정보가 포함된 User 객체를 반환합니다. 이후 login() 함수를 호출하여 해당 사용자의 세션을 생성하고 로그인 상태를 유지합니다.

from django.contrib.auth import authenticate, login
from django.shortcuts import redirect, render

def user_login_view(request):
    if request.method == "POST":
        input_id = request.POST.get("input_id")
        input_pw = request.POST.get("input_pw")
        
        # 사용자 자격 증명 검증
        authenticated_user = authenticate(request, username=input_id, password=input_pw)
        
        if authenticated_user:
            # 세션 생성 및 로그인 처리
            login(request, authenticated_user)
            return redirect("dashboard")
        return render(request, "login.html", {"error": "잘못된 아이디 또는 비밀번호입니다."})
    return render(request, "login.html")

logout()

logout() 함수는 현재 요청과 관련된 모든 세션 데이터를 파기합니다. 사용자가 로그인하지 않은 상태에서 호출되더라도 예외를 발생시키지 않습니다.

from django.contrib.auth import logout
from django.shortcuts import redirect

def user_logout_view(request):
    logout(request)
    return redirect("home")

is_authenticated 및 login_required()

현재 요청의 사용자가 인증되었는지 확인하려면 request.user.is_authenticated 속성을 사용합니다. (최신 Django 버전에서는 메서드가 아닌 속성으로 동작합니다.) 또한, login_required 데코레이터를 사용하면 뷰 수준에서 접근 제어를 쉽게 구현할 수 있습니다.

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect

# 커스텀 로그인 URL 지정
@login_required(login_url='/custom-login/')
def protected_dashboard(request):
    if request.user.is_staff:
        return redirect("admin_panel")
    return render(request, "dashboard.html")

기본 리디렉션 경로를 전역으로 변경하려면 settings.py에서 LOGIN_URL을 설정합니다.

LOGIN_URL = '/custom-login/'

사용자 생성 (create_user / create_superuser)

새로운 사용자를 생성할 때는 create_user() 또는 create_superuser() 매니저 메서드를 사용해야 합니다. 이를 통해 비밀번호가 안전하게 해싱되어 저장됩니다.

from django.contrib.auth import get_user_model

UserModel = get_user_model()

# 일반 사용자 생성
new_member = UserModel.objects.create_user(
    username="johndoe",
    password="securepassword123",
    email="john@example.com"
)

# 관리자 권한을 가진 슈퍼유저 생성
admin_user = UserModel.objects.create_superuser(
    username="adminjane",
    password="adminpass456",
    email="jane@example.com"
)

비밀번호 검증 및 변경 (check_password / set_password)

비밀번호를 변경할 때는 check_password()로 기존 비밀번호를 검증하고, set_password()로 새 비밀번호를 설정한 후 반드시 save()를 호출하여 데이터베이스에 반영해야 합니다.

from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect

@login_required
def change_password_view(request):
    message = ""
    if request.method == "POST":
        current_pw = request.POST.get("current_pw")
        new_pw = request.POST.get("new_pw")
        confirm_pw = request.POST.get("confirm_pw")
        
        if not request.user.check_password(current_pw):
            message = "기존 비밀번호가 일치하지 않습니다."
        elif new_pw != confirm_pw:
            message = "새 비밀번호 확인이 일치하지 않습니다."
        elif len(new_pw) < 8:
            message = "비밀번호는 최소 8자 이상이어야 합니다."
        else:
            request.user.set_password(new_pw)
            request.user.save()
            # 비밀번호 변경 후 세션 유지
            update_session_auth_hash(request, request.user)
            return redirect("profile")
            
    return render(request, "change_password.html", {"msg": message})

User 객체의 주요 속성

  • username, password: 기본 식별자 및 해싱된 비밀번호.
  • is_staff: Django Admin 사이트 접근 가능 여부.
  • is_active: 계정 활성화 상태. False로 설정하면 데이터를 삭제하지 않고도 로그인을 차단할 수 있습니다.
  • is_superuser: 모든 권한을 가진 슈퍼유저 여부.

커스텀 유저 모델(AbstractUser) 확장

기본 auth_user 테이블은 전화번호, 생년월일 등 비즈니스 로직에 필요한 추가 필드를 포함하고 있지 않습니다. 별도의 프로필 테이블을 OneToOneField로 연결하는 방식도 있지만, Django에서는 AbstractUser를 상속받아 커스텀 유저 모델을 정의하는 것을 공식적으로 권장합니다.

커스텀 모델 정의

AbstractUser를 상속하여 기존 인증 시스템을 그대로 활용하면서 필요한 필드를 추가합니다.

from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomMember(AbstractUser):
    """
    프로젝트 요구사항에 맞게 확장된 커스텀 유저 모델
    """
    phone_number = models.CharField(max_length=15, blank=True, null=True, verbose_name="연락처")
    birth_date = models.DateField(null=True, blank=True, verbose_name="생년월일")
    
    class Meta:
        db_table = "custom_members"
        verbose_name = "커스텀 회원"
        verbose_name_plural = "커스텀 회원 목록"
        
    def __str__(self):
        return f"{self.username} ({self.phone_number or '연락처 없음'})"

settings.py 설정 및 마이그레이션

커스텀 유저 모델을 적용하려면 settings.py에 AUTH_USER_MODEL 설정을 추가하여 Django가 기본 User 모델 대신 새로 정의한 모델을 사용하도록 지정해야 합니다.

# settings.py
AUTH_USER_MODEL = 'accounts.CustomMember'

중요: AUTH_USER_MODEL 설정은 반드시 데이터베이스를 처음 마이그레이션하기 전에 완료되어야 합니다. 이미 기본 auth_user 테이블이 생성된 상태에서 이 설정을 변경하면 외래 키 충돌 및 마이그레이션 오류가 발생할 수 있으므로, 기존 데이터베이스를 초기화하고 마이그레이션을 다시 진행해야 합니다.

태그: Django python authentication AbstractUser CustomUserModel

9월 30일 20:52에 게시됨