我的Django网站是HTTPS格式的,当我尝试从脚本向网站发布数据时,我收到了这个错误:"referer检查失败-没有referer"。这似乎是一个CSRF的问题,但我不知道如何解决它。
示例:
import requests
r = requests.post('https://mywebsite/mypage', data = {'key':'value'})
print r.text
输出如下:
[...]
<p>Reason given for failure:</p>
<pre>
Referer checking failed - no Referer.
</pre>
<p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when
<a
href="https://docs.djangoproject.com/en/1.8/ref/csrf/">Django's
CSRF mechanism</a> has not been used correctly. For POST forms, you need to
ensure:</p>
<ul>
<li>Your browser is accepting cookies.</li>
<li>The view function passes a <code>request</code> to the template's <a
href="https://docs.djangoproject.com/en/dev/topics/templates/#django.template.backends.base.Template.render"><code>render</code></a>
method.</li>
<li>In the template, there is a <code>{% csrf_token
%}</code> template tag inside each POST form that
targets an internal URL.</li>
<li>If you are not using <code>CsrfViewMiddleware</code>, then you must use
<code>csrf_protect</code> on any views that use the <code>csrf_token</code>
template tag, as well as those that accept the POST data.</li>
</ul>
[...]
在发送POST数据之前,我需要给我的头文件传递一个引用者吗?这会很不方便?或者我应该为这个页面禁用CSRF吗?
谢谢
3条答案
按热度按时间hwamh0ep1#
AFAIK,这是CSRF的目的,避免发布来自未知来源的数据。你需要csrf令牌来发布django动态生成的数据。
lb3vh1jj2#
升级Django可能会修复缺少Referer的错误。
从Django 4.0(发行说明)开始,后端会先检查
Origin
头文件,然后再回退到Referer
头文件(源代码):CsrfViewMiddleware
根据当前主机和CSRF_TRUSTED_ORIGINS
设置验证Origin标头(如果浏览器提供)。这可以防止跨子域攻击。1.此外,对于HTTPS请求,如果没有提供
Origin
报头,CsrfViewMiddleware
会执行严格的引用检查。这意味着即使子域可以设置或修改您的域中的Cookie,它也不能强制用户向您的应用发布,因为该请求不会来自您自己的确切域。ycggw6v23#
您可能正在运行反向代理,例如nginx
proxy_pass
到127.0.0.1:8000
?在这种情况下,Django希望跨站伪造保护令牌匹配主机名
127.0.0.1
,但它们将来自一个普通域(例如example.com
)。| 预期来源|实际来源|
| - ------|- ------|
| http://127.0.0.1|https://example.com|
HTTP反向代理(
example.com:80
-〉localhost:3000
)是在NodeJS应用程序中使用nginx的常用方法,但它在Django中并不适用| 面向客户端的URL|服务器代理URL|
| - ------|- ------|
| https://example.com|http://127.0.0.1:3000|
最好通过Unix套接字运行Django,而不是通过端口(
example.com:80
-〉<socket>
)。| 面向客户端的URL|服务器代理URL|
| - ------|- ------|
| https://example.com|unix:/运行/示例. com. sock|
下面是如何使用Django、Gunicorn和nginx实现这一点:
假设你有一个Django项目根目录,其中包含一个系统文件夹(
settings.py
和wsgi.py
所在的文件夹):首先,请确保您安装了Gunicorn,并且使用的是虚拟环境:
这将启动Django项目,类似于运行
python3 manage.py runserver
,只是你可以监听Unix套接字上的请求:然后使用nginx创建一个HTTP代理,通过gunicon创建的套接字传递来自客户端的HTTP请求:
/etc/nginx/sites-enabled/example.com
:确保重新启动nginx:
在这一切之后,你的csrf令牌应该与你的网站域名相匹配,你就可以登录并提交表单了。