2015-10-05 21 views
3

У меня есть эта простая кнопка Like, который хорошо работает при использовании @csrf_exempt:Как вернуть новый токен csrf в ajax POST в Django?

шаблона

<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}}"> 

Ajax

$(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) 

Однако я не» t как это обходное решение, которое игнорирует CSRF, поскольку i t может быть уязвимым. С другой стороны, мне не удалось вернуть новый токен CSRF в шаблон, поэтому я ценю ваши подсказки для интеграции CSRF в эту кнопку.

+0

[Django docs] (https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax) предлагает предоставить токен csrf в заголовке вместо данных post. – Alasdair

+0

@Alasdair, пожалуйста, дайте мне полный ответ. Я не знаю, как применять предложения документа. – Jand

+0

Я думаю, что документы довольно ясны. Что вы пробовали? Что, по-вашему, отсутствует? Какую часть вы не понимаете? – Alasdair

ответ

3

Джанго в его docs определил фактически установить заголовок запроса на AJAX, защищая при этом маркер CSRF от отправки в другие домены с использованием settings.crossDomain в JQuery 1.5.1 и новее.

Получение токена:

// 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 токен в каждом запросе AJAX, заданной на этом SO link.

$(function() { 
    $.ajaxSetup({ 
     headers: { "X-CSRFToken": getCookie("csrftoken") } 
    }); 
}); 
+0

Я добавил эти функции в свой файл ajax, и в моих представлениях удалено '@csrf_exempt', но я получаю эту ошибку в консуле' Uncaught ReferenceError: csrftoken не определен'. Есть идеи? – Jand

+0

Проверьте изменения. –

+0

Извините, я в замешательстве. Вы имеете в виду, что я должен добавить все 3 функции выше к моему ajax.js без изменения моей исходной функции ajax и представлений? – Jand

Смежные вопросы