Як відключити перевірку CSRF Django?


111

Я прокоментував процесор csrf та проміжне програмне забезпечення у settings.py:

122 
123 TEMPLATE_CONTEXT_PROCESSORS = (
124     'django.contrib.auth.context_processors.auth',
125 #    'django.core.context_processors.csrf',
126     'django.core.context_processors.request',
127     'django.core.context_processors.static',
128     'cyathea.processors.static',
129 )
130 
131 MIDDLEWARE_CLASSES = (
132     'django.middleware.common.CommonMiddleware',
133     'django.contrib.sessions.middleware.SessionMiddleware',
134 #    'django.middleware.csrf.CsrfViewMiddleware',
135     'django.contrib.auth.middleware.AuthenticationMiddleware',
136     'django.contrib.messages.middleware.MessageMiddleware',
137     'django.middleware.locale.LocaleMiddleware',
138     # Uncomment the next line for simple clickjacking protection:
139     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
140 )

Але коли я використовую Ajax для надсилання запиту, Django все одно відповідає "csrf маркер невірний або відсутній", і після додавання X-CSRFToken до заголовків запит матиме успіх.

Що тут відбувається?


Можливий дублікат: stackoverflow.com/questions/1650941/…
Рохан

Відповіді:


232

Якщо вам просто потрібні деякі види, щоб не використовувати CSRF, ви можете використовувати @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

Ви можете знайти більше прикладів та інших сценаріїв у документації про Джанго:


2
Привіт, @TheBronx, я дуже хочу знати, чому моє рішення не працює.
WoooHaaaa

1
Вибачте @MrROY Я не знаю, чому ваше рішення не працює. Я просто знаю, що @csrf_exempпрацює так, як я його використовував останнім часом без проблем. Сподіваюся, ви знайдете відповідь.
Сальваторелаб

6
@MrROY, Це справа Джанго. Більшість речей спрацьовує / не працює тільки тому, що є магічна установка, закопана вглиб бази коду.
ідурсун

2
Нагадування: якщо у вас є інші декоратори в тому ж представленні, замовлення є релевантним: тому спочатку поставте @csrf_exempt.
Патрік Басут

3
Хм - можливо, технічно правильна відповідь, але, звичайно, не те, що хотів ОП або те, що я шукав.
Danny Staple

40

Щоб відключити CSRF для представлень на основі класу, для мене працювало наступне.
Використання django 1.10 та python 3.5.2

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

@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
    def post(self, request, *args, **kwargs):
        return HttpResponse('Hello world')

32

У setting.pyпрограмі MIDDLEWARE ви можете просто видалити / прокоментувати цей рядок:

'django.middleware.csrf.CsrfViewMiddleware',

1
це працює для мене на Django 2.1, використовуючи curl як http-клієнт.
глина

1
@xtrinch Переконайтесь, що ви повністю закрили / перезапустите серверний процес. Я не думаю, що автореладор підбирає зміни
Basic

15

Для Джанго 2 :

from django.utils.deprecation import MiddlewareMixin


class DisableCSRF(MiddlewareMixin):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

Це проміжне програмне забезпечення потрібно додавати, settings.MIDDLEWAREколи це доречно (наприклад, у тестових налаштуваннях).

Примітка: налаштування більше не викликається MIDDLEWARE_CLASSES.


11

Відповідь може бути невідповідною, але я сподіваюся, що вам це допоможе

class DisableCSRFOnDebug(object):
    def process_request(self, request):
        if settings.DEBUG:
            setattr(request, '_dont_enforce_csrf_checks', True)

Наявність такого проміжного програмного забезпечення допомагає налагоджувати запити та перевіряти csrf на виробничих серверах.


Хм. Спробував це в Джанго 1.9.1. Видалено @csrf_exempt декоратор із методу та додав код вище. Отримав 403, оскільки файл cookie не встановлено.
Крейг С. Андерсон

11

Проблема тут полягає в тому, що SessionAuthentication виконує власну перевірку CSRF. Ось чому ви отримуєте помилку про відсутність CSRF навіть тоді, коли коментується середнє програмне забезпечення CSRF. Ви можете додати @csrf_exempt до кожного перегляду, але якщо ви хочете вимкнути CSRF та мати автентифікацію сеансу для всього додатка, ви можете додати додатковий проміжний продукт на зразок цього -

class DisableCSRFMiddleware(object):

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    setattr(request, '_dont_enforce_csrf_checks', True)
    response = self.get_response(request)
    return response

Я створив цей клас у myapp / middle.py. Потім імпортуйте це середнє програмне забезпечення в Middleware у settings.py

MIDDLEWARE = [
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'myapp.middle.DisableCSRFMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

Це працює з DRF на django 1.11


3
Дякуємо, що насправді ви дали відповідь на питання, а не просто розміщували рішення.
ThaJay

5

Якщо ви хочете відключити його в глобальному масштабі, ви можете написати спеціальне проміжне програмне забезпечення, наприклад це

from django.utils.deprecation import MiddlewareMixin

class DisableCsrfCheck(MiddlewareMixin):

    def process_request(self, req):
        attr = '_dont_enforce_csrf_checks'
        if not getattr(req, attr, False):
            setattr(req, attr, True)

потім додайте цей клас youappname.middlewarefilename.DisableCsrfCheckдо MIDDLEWARE_CLASSESсписків ранішеdjango.middleware.csrf.CsrfViewMiddleware



0

@WoooHaaaa деякі сторонні пакети використовують проміжне програмне забезпечення 'django.middleware.csrf.CsrfViewMiddleware'. наприклад, я використовую django-rest-oauth, і у мене є проблеми, як ви, навіть після відключення цих речей. можливо, ці пакети відповіли на ваш запит, як у моєму випадку, тому що ви використовуєте декоратор автентифікації і щось подібне.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.