首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Howto:使用Flask在WTForms中动态生成CSRF-Token

Howto:使用Flask在WTForms中动态生成CSRF-Token
EN

Stack Overflow用户
提问于 2012-08-01 20:56:25
回答 1查看 3.9K关注 0票数 11

我有一个水果表单,它有一个香蕉的FieldList对象:

代码语言:javascript
复制
bananas = FieldList(FormField(BananaForm))

在前端,最初,我将其中一个字段添加到FieldList

代码语言:javascript
复制
form.append_entry()

现在使用Javascript我成功地创建了函数,可以动态地添加(加号按钮)或删除(减号按钮)可以填充信息的BananaForm字段的数量。

FielstList自动为其所有字段创建ids。因此,为了使用js进行动态添加,我复制了HTML代码并将字段id设置为+= 1,如下所示:

第一个字段:

代码语言:javascript
复制
<tr>
  <td><input id="bananas-0-originCountry" type="text" /></td>
</tr>

+=为1的重复字段:

代码语言:javascript
复制
<tr>
  <td><input id="bananas-1-originCountry" type="text" /></td>
</tr>

当我像这样命名它们并提交表单时,WTForms将自动识别后端中添加的字段(工作正常)。

到目前为止还不错,但我的问题是:为了使表单有效,我必须向每个WTForm添加CSRF字段。在Jinja模板中,我使用以下命令:

代码语言:javascript
复制
{{ form.hidden_tag() }}

但是,当我只是用js函数复制HTML时,我遗漏了CSRF字段(因为在提交之前,后端表单对象不知道添加的FormFields)。那么如何动态地生成这些CSRF字段呢?( Ajax请求?如果是,是如何实现的?)

这应该是一个具有表单和烧瓶的标准用例。我希望我的描述是可以理解的,如果不是,请让我知道。感谢任何人的帮助!

更新:以下是我的代码

JS函数

代码语言:javascript
复制
function addBanana(){
    // clone and insert banana node
    var node = document.getElementById("fruitTable");
    var trs = node.getElementsByTagName("tr");
    var tr = trs[trs.length-2];
    var tr2 = tr.cloneNode(true);
    tr.parentNode.insertBefore(tr2, tr);

    // in order to increment label and input field ids
    function plusone(str){
        return str.replace(
            new RegExp("-(\\d+)-", "gi"),
            function($0, $1){
                var i = parseInt($1) + 1;
                return "-" + i + "-";
            }
        );
    }

    // change inputs
    var inputs = tr.getElementsByTagName("input");

    for (var i = 0; i < inputs.length; i++){
        inputs[i].setAttribute("id", plusone(inputs[i].getAttribute("id")));
    }

    var minusbutton = 
        ['<td>',
        '<button class="btn" type="button" onClick="removeBanana()"><i class="icon-black icon-minus"></i></button>',
        '</td>'
        ].join('\n');

    // only append at the first add
    // second add automatically copies minus button
    if (trs.length < 6){
        tr.innerHTML += minusbutton
    }
}

function removeBanana(){
    var node = document.getElementById("fruitTable");
    var trs = node.getElementsByTagName("tr");
    var tr = trs[trs.length-2];
    var trParent = tr.parentNode;
    trParent.removeChild(tr);
}

Jinja模板:

代码语言:javascript
复制
<form method="POST" action="newsubmit">
  {{ form.hidden_tag() }}
  <table id="fruitTable" class="table">
    {{ render_field(form.description) }}
    <tr><td><h3>Bananas</h3></td></tr>
    {% set counter = 0 %}
    {% for banana in form.bananas %} 
      <tr>
        {{ banana.hidden_tag() }}
        {% set counter = counter + 1%}
        {% for field in banana if field.widget.input_type != 'hidden' %}
          {{ render_field_oneline(field) }}
        {% endfor %}
        {% if counter > 1 %} 
          <td>
            <button class="btn" type="button" onClick="removeBanana()"><i class="icon-black icon-minus"></i></button>
          </td>
        {% endif  %} 
      </tr>
    {% endfor %}
      <tr><td></td><td><button class="btn" type="button" onClick="addBanana()"><i class="icon-black icon-plus"></i></button></td></tr>
  </table>
<input class="btn btn-primary" style="margin-left:300px;"type="submit" value="Submit" />
</form>

Jinja模板宏:

代码语言:javascript
复制
{% macro render_field_oneline(field) %}
<td>{{ field.label }}</td>
<td>{{ field(**kwargs)|safe }}
  {% if field.errors %}
  <ul class=errors>
    {% for error in field.errors %}
    <li>{{ error }}</li>
    {% endfor %}
  </ul>
  {% endif %}
</td>
{% endmacro %}

{% macro render_field(field) %}
<tr>
  {{ render_field_oneline(field) }} 
</tr>
{% endmacro %}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-19 16:34:12

我发现了它是如何工作的:

可以简单地复制CSRF-Tag。id必须相应地改变和递增,但散列可以保持不变。

我认为不可能有许多字段具有相同的CSRF-Tag散列,但它实际上做到了!

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11759769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档