Django CSRF在ajax上的失败仅在Opera上发布请求

时间:2011-06-23 08:26:18

标签: django opera django-csrf

好的,所以AJAX POST请求在Mozilla和Chromium中运行良好,但在Opera中失败。我得到标准的CSRF错误(403)。我尝试了不同版本的Opera,但在我尝试的每一个版本中都失败了。顺便说一句,我正在使用jquery / django片段在标题中设置X-CSRFToken,如下面的“糟糕的Opera请求”中所验证的那样。

我在另一个非常简单的项目中查看了一个视图,并且ajax post请求在Opera中运行良好。我查看了请求详细信息并查看了差异。好的请求没有设置任何奇怪的X-Opera-Info和其他歌剧参数甚至认为我使用相同的浏览器。如果这是问题,有没有办法删除那些额外的参数?或者是否有人对此问题有什么其他建议或想法?我知道这不是我的视图功能,因为我试图立即返回一个HttpResponse,甚至得到403'd。感谢一百万人。

####################
OPERA GOOD REQUEST
##############
Request details
POST /test HTTP/1.1 
User-Agent: Opera/9.80 (X11; Linux i686; U; en) Presto/2.7.62 Version/11.00
Host: 127.0.0.1:8000
Accept-Language: en-US,en;q=0.9
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Referer: http://127.0.0.1:8000/test
Cookie: csrftoken=1c6441404c991f7ae3b6d7d49f91f280
Cookie2: $Version=1
Connection: Keep-Alive, TE
TE: deflate, gzip, chunked, identity, trailers
Content-Length: 6
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-CSRFToken: 1c6441404c991f7ae3b6d7d49f91f280
X-Requested-With: XMLHttpRequest
Content-Transfer-Encoding: binary

###################
OPERA BAD REQUEST
####################
Request details
POST http://facebook.example.com/remove-person HTTP/1.1 
User-Agent: Opera/9.80 (X11; Linux i686; U; en) Presto/2.7.62 Version/11.00
Host: facebook.example.com
Accept-Language: en-US,en;q=0.9
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Referer: http://facebook.example.com/
Cookie: signed_request=5-f0_7pZLILrp6MLocsdMoNYAaZr-wCnU2cPbLC1bZg.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImV4cGlyZXMiOjEzMDg4MTYwMDAsImlzc3VlZF9hdCI6MTMwODgxMTQyNywib2F1dGhfdG9rZW4iOiIyMjMyNDY5NDEwMjc3MTR8Mi5BUURVRGM2ZFFLSElnN1h3LjM2MDAuMTMwODgxNjAwMC4xLTU0MDIwMjZ8b2QtX1diNTh3aG1wTnNHYUh4cTNtOVBpWkswIiwidXNlciI6eyJjb3VudHJ5IjoidXMiLCJsb2NhbGUiOiJlbl9VUyIsImFnZSI6eyJtaW4iOjIxfX0sInVzZXJfaWQiOiI1NDAyMDI2In0; csrftoken=d4cdc6a75ed264d295a410dd98982c42; fbs_223246941027714="access_token=223246941027714%7C2.AQBlhzavZjzd8c7J.3600.1308819600.1-5402026%7CdsD6VESpGJb3m0EdD1mhFZtDI24&base_domain=example.com&expires=1308819600&secret=QaTNS988wl0FU6A0LG9qDQ__&session_key=2.AQBlhzavZjzd8c7J.3600.1308819600.1-5402026&sig=61e7e13091501f35793d3cda8c20835b&uid=5402026"
Cookie2: $Version=1
Connection: Keep-Alive, TE
TE: deflate, gzip, chunked, identity, trailers
Content-Length: 14
X-Opera-Info: ID=448, p=4, f=15, sw=1440, sh=900
X-Opera-ID: e79c37b56a58510d26b56882453bddb6d2c2dae858129139113f6346ea23ca6b
X-Opera-Host: r18-02:12420
X-OA: 1322 b5834cb13259fbd50b87b576b5e8b9a8bcc1384478c2ea79cc65614dc1b67c27
X-OB: evenes
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-CSRFToken: d4cdc6a75ed264d295a410dd98982c42
X-Requested-With: XMLHttpRequest
Content-Transfer-Encoding: binary

3 个答案:

答案 0 :(得分:0)

我最近遇到了类似的问题。我第一次试图在AJAX上发布一个Django没有发送CSRF cookie的帖子。由于我无法解释的原因,这适用于除了Opera之外我尝试过的所有浏览器。

此方案为described in the Django docs,他们建议使用ensure_csrf_cookie装饰器。

如果用装饰器包装所有潜在的视图太麻烦,你可以做的另一件事是向你的基本模板添加这样的东西:

<script>
var csrf_token = "{{ csrf_token }}";
</script>

然后,无论何时执行AJAX帖子,都要将密钥对csrfmiddlewaretoken: csrf_token包含在POST数据中。

完成上述操作后,我在Opera的帖子开始工作。

答案 1 :(得分:0)

如果禁用Opera Turbo,它会起作用吗?这些额外的标题似乎与Turbo相关,也许这会产生一些差异。

答案 2 :(得分:0)

X-CSRFToken: {{ csrf_token }}}

值应该从客户端发送到AJAX请求HTTP头中,以便Django识别