django-admin startproject
로 프로젝트를 생성할 때 기본적으로 활성화되는 Django의 내장 CSRF(Cross-Site Request Forgery) 보호 기능은 CSRF 토큰을 활용하여 악의적인 요청으로부터 보호합니다. 이 미들웨어는 settings.py
.
Django 애플리케이션에 대한 모든 POST 요청에는 유효한 CSRF 토큰이 필요합니다. Django 템플릿에서는 POST 메서드를 사용하여 모든 양식에 {% csrf_token %}
를 포함함으로써 이를 달성합니다. 그러나 별도의 프런트엔드 AJAX 요청으로 CSRF 보호를 처리하려면 다른 접근 방식이 필요합니다.
이 튜토리얼에서는 별도의 프런트엔드에서 AJAX 요청으로 간단한 Django 애플리케이션을 보호하는 방법을 보여줍니다.
우리의 예시 애플리케이션에는 두 개의 엔드포인트가 있습니다.
/get-picture
: 서버에 저장된 이미지의 URL을 검색합니다./set-picture
: 서버에 저장된 이미지의 URL을 업데이트합니다.간결함을 위해 오류 처리는 생략되었습니다. 초기 백엔드 코드(urls.py
내)는 다음과 같습니다.
<code class="language-python">from django.urls import path from django.http import JsonResponse import json picture_url = "https://picsum.photos/id/247/720/405" def get_picture(request): return JsonResponse({"picture_url": picture_url}) def set_picture(request): if request.method == "POST": global picture_url picture_url = json.loads(request.body)["picture_url"] return JsonResponse({"picture_url": picture_url}) urlpatterns = [ path("get-picture", get_picture), path("set-picture", set_picture) ]</code>
해당 프런트엔드 기능(단순화):
<code class="language-javascript">// GET request to retrieve the image URL async function get_picture() { const res = await fetch("http://localhost:8000/get-picture"); const data = await res.json(); return data.picture_url; } // POST request to update the image URL async function set_picture(picture_url) { const res = await fetch("http://localhost:8000/set-picture", { method: "POST", body: JSON.stringify({ "picture_url": picture_url }) }); }</code>
CORS(Cross-Origin Resource Sharing)를 처리하기 위해 django-cors-headers
패키지를 사용합니다.
설치 django-cors-headers
:
<code class="language-bash">pip install django-cors-headers</code>
구성 settings.py
:
<code class="language-python">INSTALLED_APPS = [ "corsheaders", # ... other apps ] MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", # ... other middleware ] CORS_ALLOWED_ORIGINS = ["http://localhost:4040"] # Adjust port as needed CSRF_TRUSTED_ORIGINS = ["http://localhost:4040"] # Add your frontend origin</code>
이제 GET 요청은 올바르게 작동하지만 POST 요청은 CSRF 보호로 인해 실패합니다. 이 문제를 해결하려면 CSRF 토큰을 수동으로 관리해야 합니다.
CSRF 토큰을 제공하기 위한 새 보기를 만듭니다.
<code class="language-python">from django.views.decorators.csrf import ensure_csrf_cookie from django.http import JsonResponse @ensure_csrf_cookie def get_csrf_token(request): return JsonResponse({"success": True}) urlpatterns = [ # ... other paths path("get-csrf-token", get_csrf_token), ]</code>
토큰을 가져오도록 프런트엔드 업데이트(js-cookie
사용):
<code class="language-javascript">fetch("http://localhost:8000/get-csrf-token", { credentials: "include" });</code>
credentials: "include"
옵션은 브라우저가 모든 Set-Cookie
헤더를 처리하고 csrftoken
쿠키를 저장하도록 합니다. 브라우저 개발자 도구의 네트워크 탭을 검사하여 쿠키가 설정되어 있는지 확인하세요.
마지막으로 헤더에 CSRF 토큰을 포함하도록 set_picture
함수를 수정합니다.
<code class="language-javascript">async function set_picture(picture_url) { const res = await fetch("http://localhost:8000/set-picture", { method: "POST", credentials: "include", headers: { 'X-CSRFToken': Cookies.get("csrftoken") }, body: JSON.stringify({ "picture_url": picture_url }) }); }</code>
이렇게 하면 X-CSRFToken
쿠키의 값이 포함된 csrftoken
헤더가 추가되어 성공적인 POST 요청이 가능해집니다.
이 접근 방식에는 특히 프런트엔드와 백엔드를 서로 다른 도메인에 배포할 때 제한이 있습니다. 브라우저 보안 정책으로 인해 타사 쿠키의 설정이나 액세스가 차단되어 CSRF 토큰 관리에 영향을 미칠 수 있습니다.
위 내용은 Django 및 AJAX 요청에 CSRF 보호 사용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!