จะปิดใช้งานการตรวจสอบความถูกต้อง 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 ในส่วนหัวแล้วคำขอจะสำเร็จ

เกิดขึ้นที่นี่คืออะไร ?


อาจซ้ำกันได้: stackoverflow.com/questions/1650941/…
Rohan

คำตอบ:


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

2
คำเตือน: หากคุณมีมัณฑนากรคนอื่น ๆ ในมุมมองเดียวกันคำสั่งซื้อนั้นเกี่ยวข้อง: ให้วาง @csrf_exempt ก่อน
Patrick Bassut

3
อืม - อาจจะเป็นคำตอบที่ถูกต้องในทางเทคนิค แต่ส่วนใหญ่ไม่ใช่สิ่งที่ OP ต้องการหรือสิ่งที่ฉันกำลังมองหา
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.pyMIDDLEWARE คุณสามารถลบ / แสดงความคิดเห็นในบรรทัดนี้:

'django.middleware.csrf.CsrfViewMiddleware',

1
สิ่งนี้ใช้ได้กับฉันบน Django 2.1 โดยใช้ curl เป็นไคลเอนต์ http
ดิน

1
@xtrinch ตรวจสอบให้แน่ใจว่าคุณออก / เปิดกระบวนการเซิร์ฟเวอร์ใหม่ทั้งหมด ฉันไม่คิดว่าการปลดล็อกอัตโนมัติจะรับการเปลี่ยนแปลง
ขั้นพื้นฐาน

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 ในเซิร์ฟเวอร์ที่ใช้งานจริง


อืม. ลองสิ่งนี้ใน Django 1.9.1 นำมัณฑนากร @csrf_exempt ออกจากเมธอดและเพิ่มโค้ดด้านบน มี 403 เนื่องจากไม่ได้ตั้งค่าคุกกี้
Craig S. Anderson

11

ปัญหาคือ SessionAuthentication ดำเนินการตรวจสอบความถูกต้อง CSRF ของตนเอง นั่นคือเหตุผลที่คุณได้รับข้อผิดพลาดที่ขาดหายไปของ CSRF แม้ว่าจะมีการแสดงความคิดเห็นว่า CSRF Middleware คุณสามารถเพิ่ม @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



0

@WoooHaaaa แพ็คเกจของบุคคลที่สามบางส่วนใช้มิดเดิลแวร์ 'django.middleware.csrf.CsrfViewMiddleware' ตัวอย่างเช่นฉันใช้ django-rest-oauth และฉันมีปัญหาเหมือนคุณแม้ว่าจะปิดใช้งานสิ่งเหล่านั้นแล้วก็ตาม แพ็คเกจเหล่านี้อาจตอบสนองคำขอของคุณเช่นกรณีของฉันเนื่องจากคุณใช้มัณฑนากรรับรองความถูกต้องและอะไรทำนองนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.