Làm cách nào để tắt xác thực CSRF của Django?


111

Tôi đã nhận xét về bộ xử lý csrf và các dòng phần mềm trung gian trong 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 )

Nhưng khi tôi sử dụng Ajax để gửi yêu cầu, Django vẫn trả lời 'mã thông báo csrf không chính xác hoặc bị thiếu' và sau khi thêm X-CSRFToken vào tiêu đề, yêu cầu sẽ thành công.

Chuyện gì đang xảy ra ở đây ?


Câu trả lời:


232

Nếu bạn chỉ cần một số chế độ xem không sử dụng CSRF, bạn có thể sử dụng @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

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

Bạn có thể tìm thêm các ví dụ và các tình huống khác trong tài liệu Django:


2
Xin chào, @TheBronx, tôi thực sự muốn biết tại sao giải pháp của tôi không hoạt động.
WoooHaaaa

1
xin lỗi @MrROY Tôi không biết tại sao giải pháp của bạn không hoạt động. Tôi chỉ biết rằng nó @csrf_exemphoạt động như tôi đã sử dụng nó gần đây mà không có vấn đề gì. Mong bạn tìm được câu trả lời.
Salvatorelab

6
@MrROY, Đó là một thứ Django. Hầu hết mọi thứ hoạt động / không hoạt động chỉ vì có một cài đặt ma thuật được chôn sâu dưới cơ sở mã.
idursun

2
Lời nhắc: nếu bạn có những người trang trí khác trong cùng một chế độ xem, thứ tự có liên quan: vì vậy hãy đặt @csrf_exempt trước.
Patrick Bassut 13/1213

3
Hmm- có thể là một câu trả lời đúng về mặt kỹ thuật, nhưng chắc chắn không phải là những gì OP muốn hoặc những gì tôi đang tìm kiếm.
Danny Staple,

40

Để tắt CSRF cho các chế độ xem dựa trên lớp, cách làm sau đây phù hợp với tôi.
Sử dụng django 1.10 và 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

Trong setting.pyMIDDLEWARE, bạn chỉ cần xóa / nhận xét dòng này:

'django.middleware.csrf.CsrfViewMiddleware',

1
điều này phù hợp với tôi trên Django 2.1 bằng cách sử dụng curl làm ứng dụng khách http.
đất sét

1
@xtrinch Đảm bảo bạn thoát hoàn toàn / khởi chạy lại quy trình máy chủ. Tôi không nghĩ tính năng tự động khởi động lại nhận được thay đổi
Cơ bản

15

Đối với Django 2 :

from django.utils.deprecation import MiddlewareMixin


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

Phần mềm trung gian đó phải được thêm vào settings.MIDDLEWAREkhi thích hợp (ví dụ: trong cài đặt thử nghiệm của bạn).

Lưu ý: cài đặt không được gọi MIDDLEWARE_CLASSESnữa.


11

Câu trả lời có thể không phù hợp, nhưng tôi hy vọng nó sẽ giúp bạn

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

Có phần mềm trung gian như thế này giúp gỡ lỗi các yêu cầu và kiểm tra csrf trong máy chủ sản xuất.


Hừ! Đã thử điều này trong Django 1.9.1. Đã xóa trình trang trí @csrf_exempt khỏi phương thức và thêm mã ở trên. Có 403 vì cookie chưa được đặt.
Craig S. Anderson

11

Vấn đề ở đây là SessionAuthentication thực hiện xác thực CSRF của chính nó. Đó là lý do tại sao bạn gặp lỗi thiếu CSRF ngay cả khi Phần mềm Trung gian CSRF được nhận xét. Bạn có thể thêm @csrf_exempt vào mọi chế độ xem, nhưng nếu bạn muốn tắt CSRF và xác thực phiên cho toàn bộ ứng dụng, bạn có thể thêm một phần mềm trung gian bổ sung như thế này -

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

Tôi đã tạo lớp này trong myapp / middle.py Sau đó nhập phần mềm trung gian này vào Phần mềm trung gian trong 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',

]

Điều đó hoạt động với DRF trên django 1.11


3
Cảm ơn bạn đã thực sự đưa ra câu trả lời cho câu hỏi thay vì chỉ đăng một giải pháp.
ThaJay 14/1218

5

Nếu bạn muốn vô hiệu hóa nó trong Toàn cầu, bạn có thể viết một phần mềm trung gian tùy chỉnh, như thế này

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)

sau đó thêm lớp này youappname.middlewarefilename.DisableCsrfCheckvào MIDDLEWARE_CLASSESdanh sách, trướcdjango.middleware.csrf.CsrfViewMiddleware



0

@WoooHaaaa một số gói của bên thứ ba sử dụng phần mềm trung gian 'django.middleware.csrf.CsrfViewMiddleware'. ví dụ: tôi sử dụng django-rest-oauth và tôi gặp vấn đề như bạn ngay cả sau khi tắt những thứ đó. có thể các gói này đã phản hồi yêu cầu của bạn như trường hợp của tôi, bởi vì bạn sử dụng trình trang trí xác thực và những thứ tương tự như thế này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.