如何在代理后禁用Django的CSRF保护

3 投票
2 回答
4939 浏览
提问于 2025-04-16 10:35

我需要在一个代理后面运行一个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保护:

  1. 我在settings.py的MIDDLEWARE_CLASSES中注释掉了CsrfViewMiddleware。
  2. 我创建了一个disable.py,并将它的disableCSRF类添加到MIDDLEWARE_CLASSES中(实际上我尝试了每一个位置),就像这个网站上提到的那样(问题/1785772)。

    #disable.py
    class DisableCSRF(object):
        def process_request(self, request):
            setattr(request, '_dont_enforce_csrf_checks', True)
  3. 我又创建了一个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)
  4. 我尝试在django/middleware/csrf.py中注释掉CSRF保护机制,但我发现相关部分在第190行,而不是这个网站上提到的第160行(问题/1650941/)。

以上提到的方法都没有奏效。每次我尝试通过/admin登录时,都会得到一个403错误。

我该如何禁用Alfred的CSRF保护?是否可以只为/admin禁用它?我更希望通过像第2和第3条提到的中间件来实现,而不是像第4条那样在源代码中注释掉。如果有中间件的方法,那就太好了。

提前谢谢你! :)

2 个回答

3

你可以在视图函数上使用 @csrf_exempt 装饰器,这样就可以关闭这个视图的 CSRF 保护了。
详细信息可以查看 文档

0

问题完全出在我这边。通过查看服务器的日志,我发现不是Alfred在报错,而是代理服务器(django-httpproxy)在出问题。可能是因为两个服务器都在本地运行,而我也是从本地发送请求。我把CSRF(跨站请求伪造)在代理和Alfred上都关掉了。这样设置后,我就不再收到403错误了。

不过,django-httpproxy会丢失cookies,所以我因此无法登录。

教训是:不要把django-httpproxy当作反向代理来用。

撰写回答