[장고] 403 에러 페이지(CSRF 오류) 대신 이전 페이지로 리다이렉트하기
셋팅은 이전 글을 참고바랍니다. 이 글은 이전 글과 이어집니다.
커스텀 뷰에서 리다이렉트 수행
csrf_failure 뷰를 수정하여, 오류 발생 시 사용자를 이전 폼 페이지로 리다이렉트합니다. 리다이렉트 시에는 오류 메시지를 쿼리 파라미터로 전달할 수 있습니다.
# myapp/views.py
from django.shortcuts import redirect
from urllib.parse import urlencode
def csrf_failure(request, reason="", template_name="403_csrf.html"):
referer = request.META.get('HTTP_REFERER', '/')
params = urlencode({'csrf_error': '1'})
redirect_url = f"{referer}?{params}"
return redirect(redirect_url)
간단히 코드를 설명하자면,
모델 임포트
- redirect 함수: Django의 뷰에서 사용자를 다른 URL로 리다이렉트하는 데 사용됩니다.
- urlencode 함수: 사전(dict) 형태의 데이터를 URL 쿼리 문자열로 변환하는 데 사용됩니다.
뷰 함수 정의: csrf_failure
- CSRF 검증 실패 시 호출되는 뷰 함수입니다.
- 인자:
- request: HTTP 요청 객체.
- reason: CSRF 오류의 이유를 나타내는 문자열 (기본값: 빈 문자열).
- template_name: 사용되지 않지만 기본값은 "403_csrf.html".
이전 페이지 URL 가져오기
referer = request.META.get('HTTP_REFERER', '/')
- HTTP_REFERER 헤더에서 이전 페이지의 URL을 가져옵니다.
- HTTP_REFERER가 없을 경우 기본값으로 '/' (홈 페이지)를 사용합니다.
쿼리 매개변수 설정
params = urlencode({'csrf_error': '1'})
- 사전 형태의 데이터를 urlencode 함수를 사용하여 쿼리 문자열로 변환합니다.
- 여기서는 {'csrf_error': '1'}이라는 쿼리 매개변수를 만듭니다.
리다이렉트 URL 구성
redirect_url = f"{referer}?{params}"
이전 페이지 URL (referer)에 쿼리 매개변수 (params)를 추가하여 완전한 리다이렉트 URL을 만듭니다.
리다이렉트 실행
return redirect(redirect_url)
사용자를 redirect_url로 리다이렉트합니다.
예를 들어, 사용자가 CSRF 오류가 발생한 페이지에서 요청을 보냈고, 그 페이지의 URL이 http://example.com/form이라면:
- HTTP_REFERER는 http://example.com/form이 됩니다.
- params는 csrf_error=1로 설정됩니다.
- redirect_url은 http://example.com/form?csrf_error=1이 됩니다.
- 사용자는 http://example.com/form?csrf_error=1 URL로 리다이렉트됩니다.
이를 통해 사용자는 CSRF 오류가 발생했음을 알 수 있고, 이전 페이지로 쉽게 돌아갈 수 있습니다.
이전 폼 페이지에서 오류 메시지 처리
폼 페이지에서는 CSRF 오류가 발생했는지 확인하고, 발생했을 경우 오류 메시지를 표시하면서 새 폼을 보여줍니다.
<!-- templates/form_page.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form Page</title>
</head>
<body>
<h1>Submit Your Form</h1>
{% if request.GET.csrf_error %}
<p style="color: red;">CSRF token missing or incorrect. Please try again.</p>
{% endif %}
<form method="post" action="/submit-form/">
{% csrf_token %}
<!-- 폼 필드들 -->
<input type="text" name="field1" required>
<input type="submit" value="Submit">
</form>
</body>
</html>
위의 코드에서 csrf_failure 뷰는 CSRF 오류가 발생했을 때 사용자를 이전 페이지로 리다이렉트하며, 쿼리 파라미터로 csrf_error=1을 추가합니다.
폼 페이지에서는 이 쿼리 파라미터를 확인하여 CSRF 오류 메시지를 표시하고, 새 폼을 사용자에게 보여줍니다. 이로 인해 사용자는 CSRF 오류가 발생했을 때 새로고침된 폼으로 돌아가 다시 시도할 수 있습니다.