Django의 CSRF 유효성 검사를 비활성화하는 방법은 무엇입니까?


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을 헤더에 추가하면 요청이 성공합니다.

여기서 무슨 일이 일어나고 있습니까?


답변:


232

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 2013 년

1
죄송합니다 @MrROY 귀하의 솔루션이 작동하지 않는 이유를 모르겠습니다. 나는 @csrf_exemp최근에 문제없이 사용했기 때문에 작동 한다는 것을 알고 있습니다. 답을 찾길 바랍니다.
Salvatorelab 2013 년

6
@MrROY, 그것은 장고 일입니다. 대부분의 것은 작동하거나 작동하지 않습니다. 단지 코드베이스 깊숙이 묻혀있는 마법의 설정이 있기 때문입니다.
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
이것은 http 클라이언트로 curl을 사용하는 Django 2.1에서 나를 위해 작동합니다.
clay

1
@xtrinch 서버 프로세스를 완전히 종료 / 다시 시작해야합니다. 나는 자동 relaod이 변경 집어 생각하지 않는다
기본

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를 확인하는 데 도움이됩니다.


흠. Django 1.9.1에서 이것을 시도했습니다. 메서드에서 @csrf_exempt 데코레이터를 제거하고 위의 코드를 추가했습니다. 쿠키가 설정되지 않았기 때문에 403을 받았습니다.
크레이그 S. 앤더슨

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에이 클래스를 만든 다음 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',

]

그것은 django 1.11에서 DRF와 함께 작동합니다.


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.DisableCsrfCheckMIDDLEWARE_CLASSES목록에 추가하십시오.django.middleware.csrf.CsrfViewMiddleware



0

@WoooHaaaa 일부 타사 패키지는 'django.middleware.csrf.CsrfViewMiddleware'미들웨어를 사용합니다. 예를 들어, 나는 django-rest-oauth를 사용하고 그 것들을 비활성화 한 후에도 당신과 같은 문제가 있습니다. 인증 데코레이터와 같은 것을 사용하기 때문에 이러한 패키지가 제 경우와 같이 귀하의 요청에 응답했을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.