Django HTTPS设置:为什么同时设置SESSION_SAVE_EVERY_REQUEST和SESSION_COOKIE_SECURE会导致会话中断?
我想把我的Django应用程序限制为只能通过HTTPS访问。如果只把SESSION_SAVE_EVERY_REQUEST设置为True,或者只把SESSION_COOKIE_SECURE设置为True,一切都正常,但如果这两个都设置为True,request.session就会变成空的,这样会导致用户在网站上的身份验证出现问题。
我觉得这可能是因为我有一些HTTP请求会重定向到HTTPS,但在重定向之前会触发会话保存,这样就会创建一个新的会话ID,而这个新的会话ID是匿名用户的,因为那个HTTP请求没有发送正确的会话ID cookie。我发现,登录表单提交时返回一个会话ID cookie,但从http:.../home重定向到https:.../home时返回了一个新的会话ID cookie值,从那以后就一直使用这个新的值。
我可能可以去掉SESSION_SAVE_EVERY_REQUEST,但我想尽量保留这个功能,而且这些HTTP重定向本身也很浪费资源。
我首先尝试在我的wsgi.py中添加下面的内容,灵感来自于看到的一个问题 - https://security.stackexchange.com/questions/8964/trying-to-make-a-django-based-site-use-https-only-not-sure-if-its-secure
if not os.environ.get('DEVELOPMENT'):
os.environ['HTTPS'] = 'on'
os.environ['wsgi.url_scheme'] = 'https'
但是django.shortcuts.redirect('/')和django.contrib.auth.decorators.login_required在那之后仍然是用http重定向,而不是https,这让我很困惑……
如果这不是正确的方法,那我唯一想到的就是自定义一个SESSION_SAVE_EVERY_REQUEST的实现,只在HTTPS请求时执行。有没有人试过这个?
1 个回答
找到了!我需要设置一个选项,让Django相信我真的在使用https,尽管我是在nginx后面隐藏着:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
参考链接:https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header