2014-09-25 4 views
3

이상한 문제가 있습니다. 난 간단한 작은 애플 리케이션을 작성하고 장고보기로 다시 물건을 게시해야합니다. 여기 가이드를 따라 해요 : https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/는 아약스 헤더를 설정하고 내 JS에 다음 코드를 가지고 :Django csrf_token이 Null입니다.

function getCookie(name) { 
var cookieValue = null; 
if (document.cookie && document.cookie != '') { 
    var cookies = document.cookie.split(';'); 
    for (var i = 0; i < cookies.length; i++) { 
     var cookie = jQuery.trim(cookies[i]); 
     // Does this cookie string begin with the name we want? 
     if (cookie.substring(0, name.length + 1) == (name + '=')) { 
      cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
      break; 
     } 
    } 
} 
return cookieValue; 
} 

var csrftoken = getCookie('csrftoken'); 
console.log(csrftoken) 

function csrfSafeMethod(method) { 
    // these HTTP methods do not require CSRF protection 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 
$.ajaxSetup({ 
    beforeSend: function(xhr, settings) { 
     if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
      xhr.setRequestHeader("X-CSRFToken", csrftoken); 
     } 
    } 
}); 

내가 코드 내 HTML에서 양식을 가지고 또한

<form onsubmit="return false;"> 
       {% csrf_token %} 
       <input type="text" id="map-id-input"/> 
       <button id="map-id-btn" class='btn btn-default custom-btn'> 
        Go 
       </button> 
      </form> 

I을

$(function() { 
$("#map-id-btn").click(function() { 
    checkMapID(); 
}) 
}) 

function checkMapID() { 
    var mapId = $("#map-id-input").val(); 
    $.ajax({ 
     url: "check_map_id/", 
     type: "POST", 
     dataType: "json", 
     data: { 
      csrfmiddlewaretoken: csrftoken, 
      map_id: mapId, 
     }, 
     success: function(status_dict) { 
      if (status_dict.status === 1) { 
       $("#status").html("Valid map ID <br> Loading Data...") 
       window.location = status_dict.url; 
      } 
      else { 
       $("#status").html("Invalid map ID. Please try again, or contact ...") 
      } 
     }, 
     error: function(result) { 
      console.log(result) 
     } 
    }); 
} 

내 Javacript 모두 하나 개의 파일에 내 템플릿의 상단에 배치하십시오 위의 버튼을 클릭 할 때 실행되는 JS 코드의 조각을 가지고있다.

URL을 잡는다 뷰 'check_map_id /'입니다 :

@ensure_csrf_cookie 
def check_map_id(request): 
map_id = request.POST['map_id'] 

if map_id not in GEOJSON_LOOKUP.keys(): 
    status = json.dumps({ 
     'status': 0, 
     'url': '', 
    }) 
    return HttpResponse(status, content_type="application/json") 
else: 
    status = json.dumps({ 
     'status': 1, 
     'url': reverse('map', args=(map_id,)), 
    }) 
    return HttpResponse(status, content_type="application/json") 

지금, 나는 파이어 폭스를 사용하여 내 로컬 컴퓨터에서 응용 프로그램을 실행할 때, 나는 유효한 CSRF 토큰을 얻을 콘솔에 인쇄되고. 크롬 또는 IE의 로컬 컴퓨터에서 앱을 실행하면 null이 인쇄됩니다. 실제 사이트에서도 동일한 동작이 반복됩니다. 나는 리눅스 (민트)를 사용하고 이상하게도, 파이어 폭스에서 Windows 시스템의 응용 프로그램을 실행하면 파이어 폭스에서도 null을 반환한다. 이상한 일이 벌어지고 있습니다! 어떤 아이디어? 나는 장고 문서가 제시 한 것을 정확하게 수행하고있는 것처럼 보인다.

업데이트 : @ 인덱스 뷰에 @ensure_csrf_cookie를 추가했는데 이제 로컬 컴퓨터의 두 broswers에 토큰이 인쇄됩니다. 그러나 코드는 내 라이브 서버에서 작동하지 않습니다. js에서 임의의 console.logs를 잡아 당겨도 라이브 서버에 표시되므로 코드가 실행 중입니다. 나는 정말 실망 스럽다.

UPDATE2 : 그래서 나는 라이브 사이트에서 document.cookie 속성이 설정되어 있지 않다는 것을 확인했습니다. 나는 csrftoken = "..."쿠키가 django에 의해 설정되어 있다고 생각합니다. 내 로컬 컴퓨터에서는 설정하지만 내 라이브 사이트에서는 설정하지 않는 것 같습니다. 코드는 동일합니다. 이 세상에서 무슨 일이 벌어지고 있니?!

답변

4

확인. 나는 그 문제를 발견했다! 실제로 hs 페이지에 csrf 토큰을 보내지 않는 간단한 경우입니다. 아약스 전화에 집중하고 있었는데, 실제로는 정확했습니다.

는 실제로 문제가되는 형태가 있던 페이지로 렌더링 된 뷰를 변경 :

@ensure_csrf_cookie 
def index(request): 
    context = RequestContext(request) 
    return render_to_response('vis_it_app/index.html', context) 

의 핵심은 여기에 기본적으로 토큰뿐만 아니라 csfr을 보내 'RequestContext'입니다. 그것은 사명이었습니다 ...

그래서 요약합니다. 이 일을하려면.

  1. CSRF 토큰을 확인 실제로

  2. 확인 RequestContext 및 @ensure_csrf_cookie를 사용하여 당신이 그것을에 사용하려는 페이지로 전송됩니다 {% csrf_token %가} 양식에 어딘가에

  3. 여기에 AJAX 관련 코드를 추가하십시오 : https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax 귀하의 페이지에 자바 스크립트를 삽입하십시오

  4. ajax 데이터를 사용하여 미들웨어 토큰을 다시 보내야합니다 :

    $ 아약스 ({ URL : "...", 유형 : "POST", dataType와 "..." 데이터 : { csrfmiddlewaretoken : csrftoken, ... }

그리고 그렇게해야합니다.