polymer-cookie 生成重复的 Django csrf cookie
polymer-cookie generates duplicate Django csrf cookie
我刚 运行 遇到的奇怪问题。当我转到此页面时,Django 似乎正在生成 2 个 cookie。这两个 cookie 没有相同的标记,因此导致我的 post 失败,因为它验证了错误的 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>
,我会深入了解它的来源。
所以...您肯定是在创建第二个 cookie。这不是错误。但是让我们看看我们能否让您重回正轨。
polymer-cookie 的来源显示了几个 "hidden" 属性:
<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,但至少现在它们具有相同的值。
至于你应该如何做到这一点...跳过 polymer-cookie,只需将 {% csrftoken %}
放入你的模板中。这将创建一个名为 "csrfmiddlewaretoken" 的隐藏输入,您可以在客户端检查其值。然后你可以 return 这个价值与你的 ajax POSTs。
最后解决的办法很简单。早该考虑了。
我只是修改了我的自定义组件以接受一个名为 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>
我刚 运行 遇到的奇怪问题。当我转到此页面时,Django 似乎正在生成 2 个 cookie。这两个 cookie 没有相同的标记,因此导致我的 post 失败,因为它验证了错误的 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>
,我会深入了解它的来源。
所以...您肯定是在创建第二个 cookie。这不是错误。但是让我们看看我们能否让您重回正轨。
polymer-cookie 的来源显示了几个 "hidden" 属性:
<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,但至少现在它们具有相同的值。
至于你应该如何做到这一点...跳过 polymer-cookie,只需将 {% csrftoken %}
放入你的模板中。这将创建一个名为 "csrfmiddlewaretoken" 的隐藏输入,您可以在客户端检查其值。然后你可以 return 这个价值与你的 ajax POSTs。
最后解决的办法很简单。早该考虑了。
我只是修改了我的自定义组件以接受一个名为 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>