>백엔드 개발 >파이썬 튜토리얼 >Django 및 AJAX 요청에 CSRF 보호 사용

Django 및 AJAX 요청에 CSRF 보호 사용

DDD
DDD원래의
2025-01-07 18:15:39358검색

Using CSRF Protection with Django and AJAX Requests

CSRF 보호로 Django AJAX 요청 보호

django-admin startproject로 프로젝트를 생성할 때 기본적으로 활성화되는 Django의 내장 CSRF(Cross-Site Request Forgery) 보호 기능은 CSRF 토큰을 활용하여 악의적인 요청으로부터 보호합니다. 이 미들웨어는 settings.py.

에 추가됩니다.

Django 애플리케이션에 대한 모든 POST 요청에는 유효한 CSRF 토큰이 필요합니다. Django 템플릿에서는 POST 메서드를 사용하여 모든 양식에 {% csrf_token %}를 포함함으로써 이를 달성합니다. 그러나 별도의 프런트엔드 AJAX 요청으로 CSRF 보호를 처리하려면 다른 접근 방식이 필요합니다.

이 튜토리얼에서는 별도의 프런트엔드에서 AJAX 요청으로 간단한 Django 애플리케이션을 보호하는 방법을 보여줍니다.

애플리케이션 설정

우리의 예시 애플리케이션에는 두 개의 엔드포인트가 있습니다.

  • GET /get-picture: 서버에 저장된 이미지의 URL을 검색합니다.
  • POST /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 패키지를 사용합니다.

CORS 및 CSRF 보호 활성화

설치 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 토큰 가져오기 및 사용

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 쿠키를 저장하도록 합니다. 브라우저 개발자 도구의 네트워크 탭을 검사하여 쿠키가 설정되어 있는지 확인하세요.

POST 요청 수정

마지막으로 헤더에 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.