Django 미들웨어는 모든 요청과 응답을 감싸는 훅 체인(hook chain)이다. settings.MIDDLEWARE에 적힌 순서대로 요청이 들어가고, 응답은 그 역순으로 나온다. 세션 로드, CSRF 검사, 사용자 식별 같은 공통 처리가 여기서 일어난다.
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware", # 세션 로드
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware", # CSRF 검사
"django.contrib.auth.middleware.AuthenticationMiddleware", # request.user 채우기
"django.contrib.messages.middleware.MessageMiddleware",
]순서가 의미를 가진다. AuthenticationMiddleware는 세션에서 사용자를 읽으므로 SessionMiddleware 뒤에 와야 한다.
직접 만들기
class TimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start = time.monotonic()
response = self.get_response(request) # 다음 미들웨어·뷰
response["Server-Timing"] = f"app;dur={(time.monotonic() - start) * 1000:.0f}"
return response세션 로그인 흐름
POST /login (username, password, csrfmiddlewaretoken)
→ SessionMiddleware: 기존 세션 로드
→ CsrfViewMiddleware: 토큰 검증
→ LoginView.form_valid:
authenticate() → AUTHENTICATION_BACKENDS를 차례로 시도(ModelBackend는 비밀번호 해시 비교)
추가 검사(탈퇴·차단 계정 등)
login(request, user) → 세션에 사용자 ID 저장, 세션 키 교체
→ 응답: 성공 시 리다이렉트, 실패 시 폼 오류와 함께 로그인 화면(JSON API로 직접 만들면 401 등)login()은 로그인할 때 세션 키를 새로 발급해 세션 고정 공격(session fixation)을 막는다- 계정 상태에 따른 추가 규칙은
LoginView를 상속해form_valid를 덮어쓰거나 커스텀 인증 백엔드로 넣는다 - 비밀번호는 기본 PBKDF2(Password-Based Key Derivation Function 2)로 해시돼 있다(비밀번호 저장: 인코딩·암호화·해싱)
세션 저장과 만료는 세션 인증, CSRF 검사의 원리는 Django의 CSRF 방어, 인증과 인가의 구분은 인증과 인가를 본다. 스프링에서 같은 자리는 필터체인이 차지한다. 요청을 차례로 넘기는 구조는 책임 연쇄 패턴 패턴이다.
출처: Django 문서: Writing your own middleware · Middleware ordering · How to log a user in