2011-03-31 2 views
6

django 문서에 따르면, 1.3의 Ajax 게시 요청 (적어도 Jquery의 경우)에 대해서는 snippet을 main js 파일에 추가하면됩니다. 이 스 니펫은 쿠키에서 csrftoken을 가져온 다음 모든 아약스 요청에 대해 설정합니다. 그것이 작동하지만 csrftoken이 쿠키에없는 경우 어떻게해야합니까? 난 render_to_response 생각하고 모두 자동으로 세션에서 csrftoken을 확인하고 토큰이 없다면 우리를 위해 그것을 설정합니다. 그러나 그들은 그렇지 않습니다. 그래서, 직접 구현해야합니까? 아니면 ajax csrf 보호를 처리하는 또 다른 방법이 있을까요? 당신이 django.middleware.csrf에서 (인수로 request 객체) get_token를 호출하는 경우Django의 Ajax CSRF 문제 1.3

답변

3

쿠키는 템플릿 태그 {% csrf_token %} 중 하나가 요청을 생성하는 템플릿에 사용 된 경우는 CSRF 토큰을 포함하거나 것입니다.

get_token 함수는 request 개체의 메타 정보를 설정하여 django.middleware.csrf.CsrfViewMiddleware 미들웨어에 쿠키를 설정하도록 지시합니다.

3

Ajax의 경우 요청할 때마다 csrf 토큰을 전달해야합니다.

$.ajaxPrefilter(function(options, originalOptions, jqXHR) { 
    if(!options.crossDomain) { 
     if(options.data) { 
      options.data += "&"; 
     } else { 
      options.data = ""; 
     } 
     options.data += "csrfmiddlewaretoken={{csrf_token}}"; 
    } 
}); 
11

이미 {%의 csrf_token의 %}를 사용하는 페이지에 아무런 형태가없는, 쿠키가 전송되지 않습니다 : jQuery를 들어, 다음 코드를 사용합니다. 따라서, 언급 한 것처럼 Ajax를 이러한 페이지에서 사용하려고하면 오류가 발생합니다. 양식과 아약스 게시물의 다양한 조합이 포함 된 페이지가있는 사이트의 경우 엉뚱한 행동으로 이어질 수 있습니다.

이 이미보고 수정되었습니다 : 패치의 https://code.djangoproject.com/ticket/15354

이 솔루션은, 1.3.1 출시한다 것이라고 ensure_cookie_csrf 데코레이터이다. 해당 장식자는 1.3 또는 1.2.5에 존재하지 않습니다.

그러나 기다릴 필요가 없습니다. 그냥 AJAX 포스트에게 CSRF 양식을 포함하는 모든보기에이 줄을 추가 :

request.META["CSRF_COOKIE_USED"] = True 

예 :

def calculator(request): 
    request.META["CSRF_COOKIE_USED"] = True 
    return render_to_response('calc.html', {'form': CalcForm()}) 

는 참고 -이 그 장식이 바로 이러한 작업을 수행하는 것입니다.

+0

[CSRF Django documentation] (https : // docs.djangoproject.com/ko/dev/ref/contrib/csrf/#django.views.decorators.csrf.ensure_csrf_cookie), ensure_cookie_csrf 데코레이터는 Django 1.4에서 새로 추가되었습니다. –

+1

예, ensure_csrf_cookie 데코레이터가 장고 1.4에 설치되었습니다. 불행히도 1.3.1에는 없습니다. – bjunix

1

이 문제를 해결하기 위해 알아 낸 한 가지 방법은 기존 양식을 AJAX 데이터의 시작 지점으로 사용하는 것입니다.

<form id="ajax_form" stye="display: none;">{% csrf_token %}</form> 

은 다음 당신은 jQuery의 직렬화 기능을 통해 자바 스크립트에서 이것을 사용할 수 있습니다

var data = $('#ajax_form').serialize(); 
data += "&mydata=69"; 

내장에 당신이 문자열 연결을 사용하지 않도록 당신은 심지어 숨겨진 양식에서 숨겨진 필드를 사용할 수 있습니다 귀하의 POST 데이터.

1

@csrf_protect 데코레이터를 사용하는 경우 데코레이터를 사용하기 위해 양식이있는 뷰와 데이터가 게시 된 뷰가 모두 있는지 확인하십시오.

비슷한 문제가있었습니다. 나는 로컬에서 괜찮은 테스트를 수행 한 포스트 뷰에서만 @csrf_protect를 가졌지 만, 403 번 검증에 실패했을 때 데코레이터 토트를 추가하는 데 실패했습니다.