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.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.