validate デコレータと authenticate_form デコレータはうまく連携していないようです。これは私のテンプレートです:
<html>
<title>Test</title>
<body>
${h.secure_form('/meow/do_post')}
<input type="text" name="dummy">
<form:error name="dummy"><br>
<input type="submit" name="doit" value="Do It">
${h.end_form()}
</body>
</html>
そして、これはコントローラーです:
import logging
from pylons import request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect
from ocust.lib.base import BaseController, render
import formencode
import formencode.validators
from formencode import htmlfill
from pylons.decorators import validate
from pylons.decorators.secure import authenticate_form
class MeowForm(formencode.Schema):
allow_extra_fields = True
dummy = formencode.validators.NotEmpty()
class MeowController(BaseController):
def index(self):
return render('/index.mako')
@authenticate_form
@validate(schema=MeowForm(), form='index')
def do_post(self):
return 'posted OK'
検証が失敗した場合、フォームは @validate デコレータによって htmlfill.render を使用して再レンダリングされますが、これにより認証トークンが削除されるため、次回フォームが送信されたときに 403 CSRF 検出エラーが表示されます。
@authenticate_form が request.POST から認証トークンを削除するため、認証トークンが削除されているようです。
これを代わりに使用する場合:
@validate(schema=MeowForm(), form='index', force_defaults=False)
それは正常に動作します。force_defaults が False に設定されている場合、何か問題が発生する可能性はありますか? htmlfill のドキュメントでは、デフォルトが「フォーム送信の結果である」場合に True に設定することを推奨しているようです。