问题描述
在 Python 中使用 Tornado 库时,我遇到了一个非常不寻常的错误.似乎当我用@tornado.web.stream_request_body"装饰我的文件上传处理程序时,网络服务器会抛出错误:
Utilizing the Tornado library within Python I have come across a very unusual error. It seems that when I have decorated my file upload handler with '@tornado.web.stream_request_body' the webserver throws the error:
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 子类,具有各种辅助功能(从 cookie 和诸如此类的检索用户信息).
where my BaseHandler is a web.RequestHandler subclass with various helper functions (retrieving user info from cookies and whatnot).
在我的 HTML 模板中,我有适当的 xsrf 函数调用,如下所示:
Within my HTML template, I have the appropriate xsrf function call as seen here:
<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 输入:
and is generating the proper xsrf input within the browser:
<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 时,一切正常,一切正常.但是我觉得这并不理想.
When I turn off xsrf_cookies within the webserver settings, all is well and everything functions as normal. However I feel that this is not ideal.
虽然 xsrf_cookies 设置为 False,但如果给定一个名为stuff.txt"的文本文件,其主体为testfile",则输出为:
While xsrf_cookies is set to False, if given a text file called "stuff.txt" with a body of "testfile" the output is:
------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 验证类.
From that output, my guess is that the xsrf value is being captured by the stream_request_body and not passed to the appropriate xsrf validation class.
对此的任何帮助将不胜感激.提前致谢!
Any help on this would be greatly appreciated. Thank you in advance!
推荐答案
Tornado 目前(从 4.1 版开始)不支持流式分段上传.这意味着您希望流式传输的上传必须是简单的 PUT,而不是将上传的数据与其他表单字段(如 _xsrf
)混合的 POST.要在这种情况下使用 XSRF 保护,您必须通过 HTTP 标头 (X-Xsrf-Token
) 而不是通过表单字段传递 XSRF 令牌.不幸的是,这与非 javascript 网络表单上传不兼容;您必须有一个能够设置任意 HTTP 标头的客户端.
Tornado does not currently (as of version 4.1) support streaming multi-part uploads. This means that uploads you wish to stream must be simple PUTs, instead of a POST that mixes the uploaded data with other form fields like _xsrf
. To use XSRF protection in this scenario you must pass the XSRF token via an HTTP header (X-Xsrf-Token
) instead of via a form field. Unfortunately this is incompatible with non-javascript web form uploads; you must have a client capable of setting arbitrary HTTP headers.
这篇关于tornado.web.stream_request_body:_xsrf 丢失错误,即使在 html 中输入 _xsrf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!