Django'nun CSRF doğrulaması nasıl devre dışı bırakılır?


112

Aşağıdaki csrf işlemci ve ara yazılım satırlarını yorumladım 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 )

Ancak Ajax'ı bir istek göndermek için kullandığımda, Django hala 'csrf belirteci yanlış veya eksik' şeklinde yanıt veriyor ve X-CSRFToken'ı başlıklara ekledikten sonra istek başarılı oluyor.

Burada neler oluyor ?


Yanıtlar:


233

CSRF'yi kullanmamak için sadece bazı görünümlere ihtiyacınız varsa, şunları kullanabilirsiniz @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

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

Django belgelerinde daha fazla örnek ve başka senaryo bulabilirsiniz:


2
Merhaba @ TheBronx, çözümümün neden işe yaramadığını gerçekten bilmek istiyorum.
WoooHaaaa

1
üzgünüm @MrROY Çözümünüzün neden çalışmadığını bilmiyorum. @csrf_exempSon zamanlarda sorunsuz kullandığım gibi çalıştığını biliyorum . Umarım cevabı bulursunuz.
Salvatorelab

6
@MrROY, Bu bir Django olayı. Çoğu şey işe yarıyor / çalışmıyor çünkü kod tabanının derinliklerine gömülü sihirli bir ayar var.
idursun

2
Bir hatırlatma: aynı görünümde başka dekoratörleriniz varsa, sıra önemlidir: bu nedenle önce @csrf_exempt koyun.
Patrick Bassut

3
Hmm- belki teknik olarak doğru bir cevap, ama kesinlikle OP'nin ne istediği ya da aradığım şey değil.
Danny Staple

40

Sınıf tabanlı görünümlerde CSRF'yi devre dışı bırakmak için aşağıdakiler benim için çalıştı.
Django 1.10 ve python 3.5.2'yi kullanma

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

In setting.pyortakatmanlarına basitçe kaldırabilirsiniz / Bu satırı açıklama:

'django.middleware.csrf.CsrfViewMiddleware',

1
bu benim için Django 2.1'de curl'yi http istemcisi olarak kullanarak çalışıyor.
kil

1
@xtrinch Sunucu işleminden tamamen çıktığınızdan / yeniden başlattığınızdan emin olun. Otomatik yeniden yüklemenin değişikliği algıladığını sanmıyorum
Temel

15

İçin Django 2 :

from django.utils.deprecation import MiddlewareMixin


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

Bu ara yazılım settings.MIDDLEWAREuygun olduğunda eklenmelidir (örneğin test ayarlarınızda).

Not: ayar MIDDLEWARE_CLASSESartık çağrılmamaktadır .


11

Cevap uygunsuz olabilir ama umarım sana yardımcı olur

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

Bunun gibi bir ara yazılımın olması, isteklerde hata ayıklamaya ve üretim sunucularında csrf'yi kontrol etmeye yardımcı olur.


Hmm. Bunu Django 1.9.1'de denedi. @Csrf_exempt decorator yöntemden kaldırıldı ve yukarıdaki kod eklendi. Çerez ayarlanmadığı için 403 aldım.
Craig S. Anderson

11

Buradaki sorun, SessionAuthentication'ın kendi CSRF doğrulamasını gerçekleştirmesidir. Bu nedenle, CSRF Middleware yorumlandığında bile CSRF eksik hatası alıyorsunuz. Her görünüme @csrf_exempt ekleyebilirsiniz, ancak CSRF'yi devre dışı bırakmak ve tüm uygulama için oturum kimlik doğrulamasına sahip olmak istiyorsanız, bunun gibi ekstra bir ara yazılım ekleyebilirsiniz -

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

Bu sınıfı myapp / middle.py içinde oluşturdum Sonra bu ara yazılımı ayarlar.py içindeki Middleware'e aktarın

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',

]

Django 1.11'de DRF ile çalışır


3
Sadece bir çözüm göndermek yerine soruya cevap verdiğiniz için teşekkür ederiz.
ThaJay

5

Global'de devre dışı bırakmak istiyorsanız, bunun gibi özel bir ara yazılım yazabilirsiniz.

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)

o zaman bu sınıf eklemek youappname.middlewarefilename.DisableCsrfCheckiçin MIDDLEWARE_CLASSESönce, listelerindjango.middleware.csrf.CsrfViewMiddleware



0

@WoooHaaaa Bazı üçüncü taraf paketleri 'django.middleware.csrf.CsrfViewMiddleware' ara yazılımını kullanır. örneğin django-rest-oauth kullanıyorum ve bunları devre dışı bıraktıktan sonra bile sizin gibi sorun yaşıyorum. belki bu paketler benim durumum gibi isteğinize cevap vermiştir, çünkü siz kimlik doğrulama dekoratörü ve buna benzer bir şey kullanıyorsunuz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.