Как отключить защиту Django csrf только в определенных случаях?
Я пытаюсь написать сайт в Django, где URL-адреса API совпадают с URL-адресами пользователей. Но у меня проблемы со страницами, использующими запросы POST и CSRF. Например, если у меня есть страница /foo/add, я хочу, чтобы отправлять ей запросы POST двумя способами:
- Как конечный пользователь (аутентифицированный с использованием файла cookie сеанса), отправляющий форму. Для этого требуется защита CSRF.
- Как клиент API (аутентифицируется с использованием заголовка HTTP-запроса). Это не произойдет, если включена защита CSRF.
Я нашел различные способы отключения CSRF, такие как @csrf_exempt, но все они отключили его для всего представления. Есть ли способ включить/отключить его на более мелкомасштабном уровне? Или мне просто нужно реализовать собственную CSRF-защиту с нуля?
Ответы
Ответ 1
Существует раздел документации по защите Django CSRF под названием View для защиты одного пути, который описывает решение. Идея состоит в том, чтобы использовать @csrf_exempt
для всего представления, но когда заголовок клиента API отсутствует или недействителен, вызовите функцию
аннотируется с помощью @csrf_protect
.
Ответ 2
Изменить 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')