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

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

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

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

2 ответов


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


изменить 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')