Как отключить проверку CSRF в Django?

112

Я закомментировал строки процессора 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 в заголовки запрос будет успешным.

Что здесь происходит ?

WoooHaaaa
источник
Возможный дубликат: stackoverflow.com/questions/1650941/…
Рохан

Ответы:

233

Если вам просто нужны представления, чтобы не использовать CSRF, вы можете использовать @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

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

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

Сальваторелаб
источник
2
Привет, @TheBronx, я действительно хочу знать, почему мое решение не работает.
WoooHaaaa
1
извините @MrROY Я не знаю, почему ваше решение не работает. Я просто знаю, что это @csrf_exempработает, потому что недавно использовал без проблем. Надеюсь, ты найдешь ответ.
Salvatorelab
6
@MrROY, это вещь Django. Большинство вещей работает / не работает только потому, что глубоко в кодовой базе спрятана магическая настройка.
idursun 01
2
Напоминание: если у вас есть другие декораторы в том же представлении, порядок важен: поэтому сначала поместите @csrf_exempt.
Патрик Бассут
3
Хм - может быть, технически правильный ответ, но определенно не то, что хотел ОП или то, что я искал.
Дэнни Стейпл
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.pyMIDDLEWARE вы можете просто удалить / прокомментировать эту строку:

'django.middleware.csrf.CsrfViewMiddleware',
Rohit33
источник
1
это работает для меня на Django 2.1, используя curl в качестве http-клиента.
глина
1
@xtrinch Убедитесь, что вы полностью завершили / перезапустили серверный процесс. Я не думаю, что автоматическая перезагрузка улавливает изменения
Basic
15

Для Django 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 на производственных серверах.

Naren
источник
Хм. Пробовал это в Django 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

Если вы хотите отключить его в Global, вы можете написать собственное промежуточное ПО, например

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

JJP
источник
0

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

M.qaemi Qaemi
источник