Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Django not generate CSRF or Session Cookies behind a Varnish Proxy?

Running Django 1.2.5 on a Linux server with Apache2 and for some reason Django seems like it cannot store CSRF or Session cookies. Therefore when I try to login to the Django admin it gives me a CSRF verification error upon submitting the login form. Has anyone come up against this and found a solution?

I AM able to make a valid post when i try this at the url of my VPS that was provided by my host. Example: vps123.hostdomain.com/admin/ and for that domain the cookies DO get set. However, when I go to www.sitedomain.com/admin/ and try to login I get a CSRF 403 error saying the cookie is not there and when I check in my browsers cookies they are not set.

I have tried setting the following in my settings file:

SESSION_COOKIE_DOMAIN = 'www.sitedomain.com'
CSRF_COOKIE_DOMAIN = 'www.sitedomain.com'

Also tried:

SESSION_COOKIE_DOMAIN = 'vps123.hostdomain.com'
CSRF_COOKIE_DOMAIN = 'vps123.hostdomain.com'

I have 'django.middleware.csrf.CsrfViewMiddleware' added to my MIDDLEWARE_CLASSES in settings.py and there is a CSRF token in the form and it shows up in the POST.

I have cookies enabled. I have tried this on multiple browsers and machines.

There is a varnish proxy server sitting in front of www.sitedomain.com that I think may be part of the problem. Anyone with experience using proxy servers and Django may be able to shed some light on that.

My apache2 config:

NameVirtualHost *:80

<VirtualHost *:80>
    ServerName www.sitedomain.com
    ServerAlias www.sitedomain.com
    <Location "/">
        Options FollowSymLinks
        SetHandler python-program
        PythonInterpreter nzsite
        PythonHandler django.core.handlers.modpython
        PythonDebug On
        PythonPath "['/var/www/django_projects', '/var/www', '/usr/lib/python2.6/dist-packages'] + sys.path"
        SetEnv DJANGO_SETTINGS_MODULE project_one.settings
    </Location>
    <location "/phpmyadmin">
        SetHandler None
    </location>
</VirtualHost>

<VirtualHost *:80>
    ServerName othersite.sitedomain.com
    ServerAlias othersite.sitedomain.com
    <Location "/">
        Options FollowSymLinks
        SetHandler python-program
        PythonInterpreter ausite
        PythonHandler django.core.handlers.modpython
        PythonDebug On
        PythonPath "['/var/www/django_projects', '/var/www', '/usr/lib/python2.6/dist-packages'] + sys.path"
        SetEnv DJANGO_SETTINGS_MODULE project_two.settings
    </Location>
    <location "/phpmyadmin">
        SetHandler None
    </location>
</VirtualHost>
like image 350
thomallen Avatar asked May 19 '11 22:05

thomallen


2 Answers

The problem was that I have a Varnish Proxy server in front of my site. Varnish was taking requests and stripping cookies from them. To fix this I had to have the company that is managing the Varnish Server add '/admin' to a list of exceptions so that cookies could be passed. Sorry I can't shed more light on how the Varnish process works.

like image 153
thomallen Avatar answered Sep 29 '22 11:09

thomallen


Are you including the {{csrf_token}} in your form template?

<form autocomplete="off" method="post" action="{% url auth_login %}">{% csrf_token %}
    {{form|as_p}}
    <input type='submit' />
</form>

And including the middleware?

    'django.middleware.csrf.CsrfViewMiddleware',

From your edit, at a guess, it might have something to do with the VirtualHost configuration in Apache (if your provider is using apache). Here is an edited version of one of my apache configurations.

<VirtualHost *:80>
ServerName www.domain.com

WSGIProcessGroup my-django-site
WSGIScriptAlias / /path-to-my-django-site/wsgi/production.wsgi
Alias /media /path-to-my-django-site/media
</VirtualHost> 

It may be the case that the server name within apache has to match the domain name you are hitting the box at, along with the *_COOKIE_DOMAIN settings in your Django configuration. I'm not sure if you'll be able to change this though. Might be worth speaking to your provider if no other answers yield a win.

like image 35
Josh Smeaton Avatar answered Sep 29 '22 11:09

Josh Smeaton