如何在代理后禁用Django的CSRF保护
我需要在一个代理后面运行一个Django系统(我们叫它Alfred)。这两个系统在同一个网络上。我使用yuri vandermeer的django-httpproxy作为代理。(可以查看他的网站 yvandermeer.net)
这两个系统都在运行Django版本1.2.4。
这两个系统在同一个(封闭的)网络中,IP地址也是一样的。我把代理设置在8000端口,Alfred在1337端口。我需要通过Alfred的/admin网站登录,这个网站是Django默认提供的(我已经启用了)。通过1337端口可以正常工作,但我需要通过8000端口访问它。
当我尝试这样做时,Alfred会抛出一个403 CSRF错误,告诉我我实际上像是一个中间人(Alfred说得完全正确)。
我尝试了几种方法来禁用Alfred的CSRF保护:
- 我在settings.py的MIDDLEWARE_CLASSES中注释掉了CsrfViewMiddleware。
我创建了一个disable.py,并将它的disableCSRF类添加到MIDDLEWARE_CLASSES中(实际上我尝试了每一个位置),就像这个网站上提到的那样(问题/1785772)。
#disable.py class DisableCSRF(object): def process_request(self, request): setattr(request, '_dont_enforce_csrf_checks', True)
我又创建了一个disable.py,并将它的disableCSRF类添加到MIDDLEWARE_CLASSES中(再次尝试了每一个位置),就像这里的另一篇帖子提到的那样:http://hi.baidu.com/ledzep2/blog/item/e6b1612e21884c5c4ec2267a.html
#disable.py class DisableCSRF(object): def process_view(self, request, callback, callback_args, callback_kwargs): setattr(request, '_dont_enforce_csrf_checks', True)
我尝试在django/middleware/csrf.py中注释掉CSRF保护机制,但我发现相关部分在第190行,而不是这个网站上提到的第160行(问题/1650941/)。
以上提到的方法都没有奏效。每次我尝试通过/admin登录时,都会得到一个403错误。
我该如何禁用Alfred的CSRF保护?是否可以只为/admin禁用它?我更希望通过像第2和第3条提到的中间件来实现,而不是像第4条那样在源代码中注释掉。如果有中间件的方法,那就太好了。
提前谢谢你! :)
2 个回答
你可以在视图函数上使用 @csrf_exempt 装饰器,这样就可以关闭这个视图的 CSRF 保护了。
详细信息可以查看 文档
问题完全出在我这边。通过查看服务器的日志,我发现不是Alfred在报错,而是代理服务器(django-httpproxy)在出问题。可能是因为两个服务器都在本地运行,而我也是从本地发送请求。我把CSRF(跨站请求伪造)在代理和Alfred上都关掉了。这样设置后,我就不再收到403错误了。
不过,django-httpproxy会丢失cookies,所以我因此无法登录。
教训是:不要把django-httpproxy当作反向代理来用。