禁用字段被认为是在WTForms和Flask中进行验证

raj*_*jpy 13 python jinja2 flask wtforms

我在页面中禁用了一些字段,例如:(使用jinja2模板系统)

<html>
<body>
<form action="" method=POST>
    {{ form.name(disabled=True) }}
    {{ form.title }}
    -- submit button --
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

字段按预期在表单中禁用.

在我的views.py中:在表单提交上执行validate_on_submit()时,它在"name"字段上的验证错误失败,该字段被禁用.我希望验证忽略禁用字段.这是正确的行为吗?如果是的话,请你知道如何处理这种情况吗?

更新:

class TeamForm(wtf.Form):
    name = wtf.TextField("Team Name", validators=[validators.Required()])
    title = wtf.TextField("Title", validators=[validators.Required()])
Run Code Online (Sandbox Code Playgroud)

Cra*_*ast 22

这实际上是一个有趣的问题,WTForms解决它的方式是故意需要显式的东西,因为它与安全性有关,不允许用户伪造输入.

所以意图是,"经理"不能编辑名称,而"管理员"可以.

乍一看这似乎很明显,只需在HTML中禁用该字段,然后按如下方式编写视图:

def edit_team():
    form = TeamForm(request.POST, obj=team)
    if request.POST and form.validate():
        form.populate_obj(team) # <-- This is the dangerous part here
        return redirect('/teams')
    return render('edit_team.html')
Run Code Online (Sandbox Code Playgroud)

如上所述,这是一个主要的安全风险,因为HTML表单中的disabled属性仅限于客户端.任何拥有HTML检查器的人(即FireBug,webkit文档检查器等)都可以删除此属性,或者有人可以简单地发出如下请求:

POST /edit_team/7 HTTP/1.0
Content-Type: application/x-urlencoded

team=EVILTEAMNAME&title=foo
Run Code Online (Sandbox Code Playgroud)

那么问题当然是,我们如何在服务器端正确选择这个,对应于这样做的适当方式?WTForms的正确方法是首先没有该领域.有几种方法可以做到这一点,一种是使用表单组合,例如有ManagerTeamForm和AdminTeamForm(有时候这样更好),但有时候使用del来删除特定字段会更容易.

所以这是你如何写你的观点,而不是有验证问题:

def edit_team():
    form = TeamForm(request.POST, obj=team)
    if user.role == 'manager':
        del form.name
    if request.POST and form.validate():
        form.populate_obj(team)
        return redirect('/teams')
    return render('edit_team.html')
Run Code Online (Sandbox Code Playgroud)

并快速修改模板:

<html>
<body>
<form action="" method=POST>
    {% if 'name' in form %}
        {{ form.name() }}
    {% else %}
        {{ team.name|e }}
    {% endif %}
    {{ form.title }}
    -- submit button --
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

wtforms最佳实践的一些参考:

  • @rajpy,也许“禁用”是一个错误的名词。该属性控制是否允许用户更改值,而不控制它是否实际上影响服务器上的行为。有时,向用户显示哪些数据正在发送到服务器但不允许他们更改值会很有帮助。 (2认同)