Как я могу отключить защиту Django csrf только в определенных случаях?

Я пытаюсь написать сайт в Django, где URL-адреса API совпадают с URL-адресами, ориентированными на пользователя. Но у меня проблемы со страницами, которые используют POST-запросы и защиту CSRF. Например, если у меня есть страница / foo / add, я хочу иметь возможность отправлять на нее запросы POST двумя способами:

  1. Как конечный пользователь (аутентифицированный с помощью файла cookie сеанса), отправляющий форму. Это требует защиты CSRF.
  2. В качестве клиента API (аутентифицированного с использованием заголовка HTTP-запроса). Это не удастся, если включена защита CSRF.

Я нашел различные способы отключения CSRF, такие как @csrf_exempt, но все они отключают его для всего представления. Есть ли способ включить / отключить его на более детальном уровне? Или мне просто придется внедрять собственную защиту от CSRF с нуля?


person lucas    schedule 07.07.2012    source источник
comment
Вы проверяли документы по защите от csrf?   -  person machaku    schedule 07.07.2012
comment
Я читал отрывки из этого, но явно не читал все сценарии. Спасибо!   -  person lucas    schedule 07.07.2012


Ответы (3)


В документации Django по защите CSRF есть раздел Просмотр требуется защита для одного пути, который описывает решение. Идея состоит в том, чтобы использовать @csrf_exempt во всем представлении, но когда заголовок клиента API отсутствует или недействителен, вызовите функцию, помеченную @csrf_protect.

person Daniel Trebbien    schedule 07.07.2012

Изменить urls.py

Если вы управляете своими маршрутами в urls.py, вы можете заключить желаемые маршруты в csrf_exempt(), чтобы исключить их из промежуточного программного обеспечения проверки CSRF.

например,

from django.views.decorators.csrf import csrf_exempt
urlpatterns = patterns(
    # ...
    # Will exclude `/api/v1/test` from CSRF 
    url(r'^api/v1/test', csrf_exempt(TestApiHandler.as_view()))
    # ...
)

Или как декоратор

Некоторые могут найти использование декоратора @csrf_exempt более подходящим для своих нужд.

например,

from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')
person Jossef Harush    schedule 30.06.2015

Если вы используете базовое представление класса (CBV) и хотите использовать декоратор csrf_exempt, вам нужно будет использовать декоратор метода.

from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt

@method_decorator(csrf_exempt, name='dispatch')
class MyView(View):
    def post(self, request):
        pass  # my view code here
person Thomas Turner    schedule 18.12.2019
comment
Вы уверены в этом решении? - person Save; 28.05.2021