2015-10-05 45 views
3

我有這個簡單的Like按鈕與@csrf_exempt使用時效果很好:如何在Django的ajax POST中返回新的csrf標記?

模板

<p id="like_count"> {{ topic.likes }}</p> 
<span data-type="topic" title="Like">  {% csrf_token %} 
<i class="fa fa-thumbs-up" id="liket" name="{{topic.id}}"> 

阿賈克斯

$(function(){ 
$('#liket').click(function(){ 
     $.ajax({ 
       type: "POST", 
       url: "/like/", 
       data: { 
       'topic_id': $(this).attr('name'), 
       'csrfmiddlewaretoken': '{{csrf_token}}' 
       }, 
       success: tlikeSuccess, 
       dataType: 'html'    
       }); 
    }); 

}); 
function tlikeSuccess(data, textStatus, jqXHR) 
{ 
    $('#like_count').html(data); 
} 

和看法:

#@csrf_exempt 
def topic_like(request): 

    args = {} 
    if request.method == 'POST': 

     user = request.POST.get('user') 
     lu= request.user #User.objects.get(username= user) 
     topic_id = int(request.POST.get('topic_id')) 

     try: 
      liked_topic = Topic.objects.get(id = topic_id) 
     except: 
      liked_topic = None 

     if TopicLike.objects.filter(liker=request.user.id, topic=topic_id).exists(): 

      liked_topic.likes -=1 
      liked_topic.save() 
      TopicLike.objects.filter(topic=topic_id, liker=request.user.id).delete() 

     else:    
      liked_topic.likes +=1 
      liked_topic.save() 
      newliker = TopicLike(topic=topic_id, liker=request.user.id) 
      newliker.save()   


    #args.update(csrf(request)) 
    args['likes'] = str(liked_topic.likes) 
    return render(request, 'ajax_like.html', args) 

但是我不不喜歡這種忽略CSRF的解決方法,就像我一樣噸可能是脆弱的。 另一方面,我無法設法將新的CSRF令牌返回給模板,所以我感謝您將CSRF集成到此按鈕中的提示。

+0

[Django文檔](https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax)建議在標題中提供csrf標記,而不是在發佈數據中提供。 – Alasdair

+0

@阿拉斯代爾請給我一個完整的答案。我不知道如何應用文檔的建議。 – Jand

+0

我認爲文檔非常清晰。你嘗試了什麼?你覺得缺少什麼?你不明白哪一部分? – Alasdair

回答

3

Django的在其docs定義實際設置在AJAX請求報頭,同時保護CSRF令牌被髮送到jQuery中1.5.1和較新的使用settings.crossDomain其他領域。

獲取令牌:

// using jQuery 
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'); 

在報頭中設置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); 
     } 
    } 
}); 

還嘗試這種方法嵌入CSRF令牌在此SO link.

給出每個AJAX請求
$(function() { 
    $.ajaxSetup({ 
     headers: { "X-CSRFToken": getCookie("csrftoken") } 
    }); 
}); 
+0

我將這些函數添加到了我的ajax文件中,並在我的視圖中刪除了'@csrf_exempt',但是我在consul'Uncaught ReferenceError:csrftoken未定義'中出現此錯誤。有任何想法嗎? – Jand

+0

檢查編輯。 –

+0

對不起,我很困惑。你的意思是我應該將以上所有3個函數添加到我的ajax.js而不改變我原來的ajax函數和視圖? – Jand

相關問題