CSRF django nginx与来自cloudflare的ssl

时间:2016-01-05 15:53:53

标签: django ssl nginx csrf

背景

我正在尝试配置我的Django应用程序以使用cloudflare提供的ssl。我有与this answer大致相同的设置,并遵循相同的解决方案。

问题:

这已经让我好几个星期了(请帮助!),因为我一个网络/安全人员,只需要一个能避免让我瞪眼的解决方案但保持网站安全。

我目前收到https://www.domain.co.ukhttps://domain.co.uk

不匹配的CSRF问题

配置

Settings.py

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
USE_X_FORWARDED_HOST = True

nginx的:

server {

    listen 80 default_server;

    server_name domain.co.uk www.domain.co.uk;
    access_log off;

    location /static/ {
        alias /static/;
    }


    location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_set_header X-Real-IP $remote_addr;
            add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';

            proxy_set_header X-Scheme $scheme;
            proxy_set_header X-Forwarded-Protocol $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            }
}

Cloudflare DNS:

A domain.co.uk  points to <ip> Automatic
CNAME www is an alias of domain.co.uk Automatic 

加成

此外,我还有域名.com,想知道如何最好地设置它,以便它也是ssl。

2 个答案:

答案 0 :(得分:3)

您需要设置发送CSRF cookie的域。尝试在您的设置中将CSRF_COOKIE_DOMAIN设置为".domain.co.uk",将CSRF_COOKIE_SECURE设置为True

第4点值得阅读https://docs.djangoproject.com/en/1.9/ref/csrf/#how-it-works

答案 1 :(得分:1)

就个人而言,我会把你的配置放在nginx端,而不是Django端。这样,当您进行本地开发时,您可以验证您的CSRF并确保一切正常。确保它确实有效...如果你不能在没有nginx配置的情况下让它在本地工作,那么还有另一个与你的服务器配置无关的问题。然后,应该可以在没有特定Django设置或库的情况下使一切在服务器上以相同的方式工作。

对于你的nginx配置,解决方案可能是我们answer like this到301重定向所有www。到非www,以及将所有http重定向到https。

然后,您可以在nginx中重命名此行:

server_name domain.co.uk www.domain.co.uk;

为:

server_name domain.co.uk;  # This assumes you're directing www. to non-www

应解决您的CSRF问题...因为您只会引用一个域而不是上面的两个域。

301重定向的额外好处是您可以避免对有机搜索的任何重复内容处罚。

[编辑]您似乎正在使用CNAME重定向www。到非www,所以你可以简单地使用https到非https 301重定向从我上面引用的答案。