개요
Django의 auth 모듈은 웹 애플리케이션에서 사용자 인증, 권한 부여, 그룹 관리를 위한 강력한 내장 기능을 제공합니다. 이 모듈은 특히 admin 사이트와 긴밀하게 연동되어 개발 초기 단계부터 안전한 사용자 관리 체계를 구축할 수 있게 도와줍니다.
핵심 인증 메서드
사용자 인증: authenticate()
비밀번호는 해시 처리되므로 직접 비교는 불가능합니다. 대신 authenticate() 함수를 사용해 요청 객체와 함께 자격 증명을 검증해야 합니다.
from django.contrib import auth
from django.http import HttpResponse
def login_view(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 올바른 인증 방식
user = auth.authenticate(request, username=username, password=password)
if user is not None:
return HttpResponse("로그인 성공")
else:
return HttpResponse("잘못된 계정 정보")
return render(request, 'login.html')
세션 로그인: login()
성공적으로 인증된 사용자는 login() 함수로 세션에 등록하여 상태를 유지합니다. 이후 모든 뷰에서 request.user로 접근 가능합니다.
if user:
auth.login(request, user)
# 이제부터 request.user는 인증된 사용자 객체입니다.
로그아웃 처리: logout()
현재 세션을 종료하고 익명 사용자 상태로 전환합니다.
def logout_view(request):
auth.logout(request)
return redirect('/home/')
로그인 상태 확인: is_authenticated
속성 is_authenticated는 사용자의 로그인 여부를 판단하는 데 사용됩니다. 템플릿 및 뷰 모두에서 활용 가능합니다.
- 뷰 내에서:
if request.user.is_authenticated:
print(f"{request.user.username} 님이 접속 중입니다.")
else:
print("익명 사용자")
- 템플릿에서:
{% if request.user.is_authenticated %}
안녕하세요, {{ request.user.username }}!
{% else %}
<a href="/login/">로그인이 필요합니다</a>
{% endif %}
접근 제어: @login_required
특정 뷰에 대한 접근을 로그인된 사용자로 제한할 수 있습니다. 미认証 시 지정된 URL로 리디렉션됩니다.
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def dashboard(request):
return render(request, 'dashboard.html')
리디렉션 시 ?next=/dashboard/ 파라미터가 추가되어, 로그인 후 원래 요청한 페이지로 자동 이동할 수 있습니다.
사용자 생성: create_user() / create_superuser()
새 사용자를 안전하게 생성할 때는 비밀번호가 자동으로 해싱되는 내장 메서드를 사용해야 합니다.
from django.contrib.auth.models import User
# 일반 사용자 생성
user = User.objects.create_user(
username='jane',
password='securepass123'
)
# 슈퍼유저 생성 (manage.py createsuperuser 내부에서 사용)
superuser = User.objects.create_superuser(
username='admin',
password='admin123'
)
비밀번호 검증 및 변경
기존 비밀번호 일치 여부를 확인하려면 check_password() 메서드를 사용합니다.
user = User.objects.get(username='john')
if user.check_password('raw_password'):
print("비밀번호 일치")
비밀번호를 변경할 때는 반드시 set_password()와 save()를 함께 호출해야 반영됩니다.
def change_password_view(request):
if request.method == 'POST':
old = request.POST.get('old_pwd')
new = request.POST.get('new_pwd')
if request.user.check_password(old):
request.user.set_password(new)
request.user.save() # 저장 필수!
return redirect('/login/')
else:
return HttpResponse("기존 비밀번호 오류")
return render(request, 'change_pwd.html')
User 모델 주요 속성
- is_staff: Django admin에 접근 가능한지 여부. True일 경우 관리자 사이트 로그인이 가능합니다.
- is_superuser: 모든 데이터에 대한 무제한 접근 권한을 가집니다.
is_staff와 함께 설정됩니다. - is_active: 계정 활성화 상태를 나타냅니다. 로그인 차단이 필요할 때 False로 설정하면 삭제 없이 계정을 비활성화할 수 있습니다 (예: 다중 실패 시도 후 잠금).
기본 User 모델 확장 방법
Django의 기본 auth_user 테이블은 필드 추가가 제한적이므로, 다음과 같은 두 가지 방법으로 확장할 수 있습니다.
방법 1: OneToOneField 연결
기존 User와 1:1 관계를 맺는 별도 모델을 생성합니다. 기존 코드 호환성이 높습니다.
from django.contrib.auth.models import User
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=15)
address = models.TextField()
방법 2: AbstractUser 상속 (권장)
프로젝트 초기에 사용자 정의 모델을 설계할 때 추천되는 방식입니다. 기존 필드를 재정의하거나 새 필드를 추가할 수 있습니다.
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
phone = models.CharField(max_length=15)
address = models.CharField(max_length=100)
# 기존 필드(username, email 등)도 재정의 가능
이후 settings.py에 아래 설정을 추가해야 합니다:
AUTH_USER_MODEL = 'myapp.User' # 앱이름.모델이름
기존 프로젝트에서 AUTH_USER_MODEL 교체 시 절차
프로젝트 중간에 사용자 모델을 변경하려면 데이터베이스 마이그레이션 충돌을 해결해야 하므로 신중한 절차가 필요합니다.
- 기존 데이터를 백업합니다.
- DB를 삭제하고 새로 생성합니다.
- 모든 앱의
migrations/디렉터리 내 파일(__init__.py제외)을 제거합니다. - Django 내장 앱인
auth와admin의 마이그레이션 파일도 동일하게 삭제합니다.
경로 예:site-packages/django/contrib/auth/migrations/ makemigrations및migrate명령어로 새로운 스키마를 적용합니다.- 백업한 데이터를 수동 또는 스크립트로 복원합니다.
⚠️ 이 작업은 프로덕션 환경에서는 매우 위험하며, 가능하면 초기 설계 단계에서 AUTH_USER_MODEL을 결정하는 것이 좋습니다.