tornado.web.stream_request_body:即使在 html 内输入 _xsrf,也会出现 _xsrf 丢失错误
tornado.web.stream_request_body: _xsrf missing error even with _xsrf input within html
利用 Python 中的 Tornado 库,我遇到了一个非常不寻常的错误。似乎当我用'@tornado.web.stream_request_body'装饰我的文件上传处理程序时,网络服务器抛出错误:
WARNING:tornado.general:403 POST /upload (ip-address): '_xsrf' argument missing from POST
WARNING:tornado.access:403 POST /upload (ip-address) 1.44ms
上传控制代码如下:
@tornado.web.stream_request_body
class Upload(BaseHandler):
def prepare(self):
print self.request.headers
def data_received(self,chunk):
print chunk
@tornado.web.authenticated
def post(self):
self.redirect("/")
我的 BaseHandler 是一个 web.RequestHandler subclass,具有各种辅助功能(从 cookie 和诸如此类的东西中检索用户信息)。
在我的 HTML 模板中,我有适当的 xsrf 函数调用,如下所示:
<form enctype="multipart/form-data" action="/upload" method="post" id="upload_form" class="form-upload">
{% raw xsrf_form_html() %}
<input type="file" name="upFile" required/>
<button class="btn btn-lg btn-primary btn-block-submit" type="submit">Submit</button>
</form>
并且正在浏览器中生成正确的 xsrf 输入:
<form enctype="multipart/form-data" action="/upload" method="post" id="upload_form" class="form-upload">
<input type="hidden" name="_xsrf" value="2|787b7c6e|4a82eabcd1c253fcabc9cac1e374e913|1430160367"/>
<input type="file" name="upFile" required/>
<button class="btn btn-lg btn-primary btn-block-submit" type="submit">Submit</button>
</form>
当我在网络服务器设置中关闭 xsrf_cookies 时,一切正常,一切正常。不过我觉得这样不太理想。
虽然 xsrf_cookies 设置为 False,如果给定一个名为 "stuff.txt" 的文本文件,正文为 "testfile",则输出为:
------WebKitFormBoundary4iHkIqUNgfqVErRB
Content-Disposition: form-data; name="_xsrf"
2|787b7c6e|4a82eabcd1c253fcabc9cac1e374e913|1430160367
------WebKitFormBoundary4iHkIqUNgfqVErRB
Content-Disposition: form-data; name="upFile"; filename="stuff.txt"
Content-Type: text/plain
testfile
------WebKitFormBoundary4iHkIqUNgfqVErRB--
根据该输出,我的猜测是 xsrf 值被 stream_request_body 捕获并且没有传递给适当的 xsrf 验证 class.
如有任何帮助,我们将不胜感激。提前致谢!
Tornado 目前(从 4.1 版开始)不支持流式传输 multi-part 上传。这意味着您希望流式传输的上传必须是简单的 PUT,而不是将上传的数据与其他表单字段(如 _xsrf
)混合的 POST。要在这种情况下使用 XSRF 保护,您必须通过 HTTP header (X-Xsrf-Token
) 而不是通过表单字段传递 XSRF 令牌。不幸的是,这与 non-javascript 网络表单上传不兼容;你必须有一个能够设置任意 HTTP headers.
的客户端
利用 Python 中的 Tornado 库,我遇到了一个非常不寻常的错误。似乎当我用'@tornado.web.stream_request_body'装饰我的文件上传处理程序时,网络服务器抛出错误:
WARNING:tornado.general:403 POST /upload (ip-address): '_xsrf' argument missing from POST
WARNING:tornado.access:403 POST /upload (ip-address) 1.44ms
上传控制代码如下:
@tornado.web.stream_request_body
class Upload(BaseHandler):
def prepare(self):
print self.request.headers
def data_received(self,chunk):
print chunk
@tornado.web.authenticated
def post(self):
self.redirect("/")
我的 BaseHandler 是一个 web.RequestHandler subclass,具有各种辅助功能(从 cookie 和诸如此类的东西中检索用户信息)。
在我的 HTML 模板中,我有适当的 xsrf 函数调用,如下所示:
<form enctype="multipart/form-data" action="/upload" method="post" id="upload_form" class="form-upload">
{% raw xsrf_form_html() %}
<input type="file" name="upFile" required/>
<button class="btn btn-lg btn-primary btn-block-submit" type="submit">Submit</button>
</form>
并且正在浏览器中生成正确的 xsrf 输入:
<form enctype="multipart/form-data" action="/upload" method="post" id="upload_form" class="form-upload">
<input type="hidden" name="_xsrf" value="2|787b7c6e|4a82eabcd1c253fcabc9cac1e374e913|1430160367"/>
<input type="file" name="upFile" required/>
<button class="btn btn-lg btn-primary btn-block-submit" type="submit">Submit</button>
</form>
当我在网络服务器设置中关闭 xsrf_cookies 时,一切正常,一切正常。不过我觉得这样不太理想。
虽然 xsrf_cookies 设置为 False,如果给定一个名为 "stuff.txt" 的文本文件,正文为 "testfile",则输出为:
------WebKitFormBoundary4iHkIqUNgfqVErRB
Content-Disposition: form-data; name="_xsrf"
2|787b7c6e|4a82eabcd1c253fcabc9cac1e374e913|1430160367
------WebKitFormBoundary4iHkIqUNgfqVErRB
Content-Disposition: form-data; name="upFile"; filename="stuff.txt"
Content-Type: text/plain
testfile
------WebKitFormBoundary4iHkIqUNgfqVErRB--
根据该输出,我的猜测是 xsrf 值被 stream_request_body 捕获并且没有传递给适当的 xsrf 验证 class.
如有任何帮助,我们将不胜感激。提前致谢!
Tornado 目前(从 4.1 版开始)不支持流式传输 multi-part 上传。这意味着您希望流式传输的上传必须是简单的 PUT,而不是将上传的数据与其他表单字段(如 _xsrf
)混合的 POST。要在这种情况下使用 XSRF 保护,您必须通过 HTTP header (X-Xsrf-Token
) 而不是通过表单字段传递 XSRF 令牌。不幸的是,这与 non-javascript 网络表单上传不兼容;你必须有一个能够设置任意 HTTP headers.