奇怪的问题我刚碰到。当我转到这个页面时,Django似乎正在生成2个cookie。这两个cookie没有相同的令牌,因此导致我的帖子失败,因为它验证了错误的cookie。
任何人都知道为什么会发生这种情况?
视图中没有什么特别之处:
class ListingDetailView(TemplateView):
template_name = "bidding/listing_detail.html"
def get(self, request, *args, **kwargs):
c = self.get_context_data(**kwargs)
c['listing'] = get_object_or_404(Listing, id=kwargs['id'])
return self.render_to_response(c)
...虽然看起来违规代码可能在我的一个自定义组件中(当我隐藏它时,生成额外的cookie):
<polymer-element name="bts-place-bid" attributes="href">
<template>
<polymer-cookie id="csrfcookie" name="csrftoken"></polymer-cookie>
<core-ajax
id="bidxhr"
method="post"
body=""
url="{{ href }}"
headers='{"X-CSRFToken": "{{ csrftoken }}"}'
on-core-response="{{ handleResponse }}">
</core-ajax>
<core-style ref="bts-place-bid"></core-style>
<paper-button on-click="{{ toggleDialog }}">Place Bid</paper-button>
<paper-action-dialog heading="Place Bid"
transition="core-transition-center"
id="bidDialog">
<core-style ref="bts-bid-dialog"></core-style>
<bts-field>
<label for="id_amount">Bid Amount in Rands</label>
<input type="number" name="amount" id="id_amount" value="{{ amount }}">
</bts-field>
<bts-field vertical layout>
<label for="id_proposal">Short note or proposal for this bid</label>
<textarea rows="4" id="id_proposal" name="proposal" value="{{ proposal }}"></textarea>
</bts-field>
<paper-button dismissive><core-icon icon="cancel"></core-icon> Cancel</paper-button>
<paper-button on-click="{{ placeBid }}" affirmative><core-icon icon="note-add"></core-icon> Place Bid!</paper-button>
</paper-action-dialog>
<paper-toast id="toastMsg" text=""></paper-toast>
</template>
<script>
Polymer({
amount: 0,
proposal: "",
bidPayload: "",
ready: function() {
this.csrftoken = this.$.csrfcookie.value;
},
toggleDialog: function(ev, detail, sender) {
this.$.bidDialog.toggle();
},
placeBid: function(ev, detail, sender) {
this.$.toastMsg.text = "Placing bid, please wait..."
this.$.toastMsg.show();
this.$.bidxhr.body = "amount=" + this.amount + "&proposal=" + this.proposal;
this.$.bidxhr.go();
},
handleResponse: function(ev, detail, sender) {
this.$.toastMsg.text = "Bid placed, refreshing...";
this.$.toastMsg.show();
// Auto refresh the page...
window.location = window.location;
}
});
</script>
</polymer-element>
我怀疑问题可能出在<polymer-cookie>
,我会稍微挖掘它的来源。
答案 0 :(得分:1)
所以......你肯定是在创建第二个cookie。这不是一个错误。但是,让我们看看我们是否能让你回到正轨。
聚合物饼干的来源显示了几个“隐藏”属性:
<polymer-element name="polymer-cookie" hidden attributes="name value expires secure domain path max-age">
您设置的cookie与CSRF令牌具有相同的名称,但是具有任意值。因此,最简单的修复方法可能是指定您希望它具有的值:
<polymer-cookie id="csrfcookie" name="csrftoken" value="{{ csrftoken }}"></polymer-cookie>
我希望您仍然会有重复的Cookie,但至少现在它们具有相同的值。
至于你应如何这样做...跳过聚合物cookie并将{% csrftoken %}
放在你的模板中。这将创建一个名为“csrfmiddlewaretoken”的隐藏输入,您可以检查客户端的值。然后,您可以使用ajax POST返回该值。
答案 1 :(得分:1)
最后,解决方案非常简单。应该早点考虑一下。
我只是修改了我的自定义组件以接受一个名为csrftoken的额外属性,对于这个属性我只能传递django {{ csrf_token }}
变量。无需查找cookie,无需添加额外的输入字段等。
这是最后一部分:
<polymer-element name="bts-place-bid" attributes="href csrftoken">
<template>
<core-ajax
id="bidxhr"
method="post"
body=""
url="{{ href }}"
headers='{"X-CSRFToken": "{{ csrftoken }}"}'
on-core-response="{{ handleResponse }}">
</core-ajax>
<core-style ref="bts-place-bid"></core-style>
<paper-button on-click="{{ toggleDialog }}">Place Bid</paper-button>
<paper-action-dialog heading="Place Bid"
transition="core-transition-center"
id="bidDialog">
<core-style ref="bts-bid-dialog"></core-style>
<bts-field>
<label for="id_amount">Bid Amount in Rands</label>
<input type="number" name="amount" id="id_amount" value="{{ amount }}">
</bts-field>
<bts-field vertical layout>
<label for="id_proposal">Short note or proposal for this bid</label>
<textarea rows="4" id="id_proposal" name="proposal" value="{{ proposal }}"></textarea>
</bts-field>
<paper-button dismissive><core-icon icon="cancel"></core-icon> Cancel</paper-button>
<paper-button on-click="{{ placeBid }}" affirmative><core-icon icon="note-add"></core-icon> Place Bid!</paper-button>
</paper-action-dialog>
<paper-toast id="toastMsg" text=""></paper-toast>
</template>
<script>
Polymer({
amount: 0,
proposal: "",
bidPayload: "",
toggleDialog: function(ev, detail, sender) {
this.$.bidDialog.toggle();
},
placeBid: function(ev, detail, sender) {
this.$.toastMsg.text = "Placing bid, please wait..."
this.$.toastMsg.show();
this.$.bidxhr.body = "amount=" + this.amount + "&proposal=" + this.proposal;
this.$.bidxhr.go();
},
handleResponse: function(ev, detail, sender) {
this.$.toastMsg.text = "Bid placed, refreshing...";
this.$.toastMsg.show();
// Auto refresh the page...
window.location = window.location;
}
});
</script>
</polymer-element>
...然后在主django模板中使用它:
<bts-place-bid href="{% url 'bidding_listing_bid' id=listing.id %}"
csrftoken="{{ csrf_token }}"></bts-place-bid>