polymer-cookie生成重复的Django csrf cookie

时间:2015-03-09 20:05:44

标签: django polymer django-csrf

enter image description here

奇怪的问题我刚碰到。当我转到这个页面时,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>,我会稍微挖掘它的来源。

2 个答案:

答案 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>