Authentication and Browser Caching in Django, part II

The other day I wrote about turning off browser caching when a user is logged in. Since I’m apparently a clueless n00b, it only occurred to me later that this is the sort of thing belongs in middleware. That way you don’t have to modify individual views, and it works for flatpages as well. Here’s the middleware; it should go in MIDDLEWARE_CLASSES before sessions and flatpages:

import re

def _add_to_header(response, key, value):
    if response.has_header(key):
        values = re.split(r'\s*,\s*', response[key])
        if not value in values:
            response[key] = ', '.join(values + [value])
    else:
        response[key] = value

def _nocache_if_auth(request, response):
    if request.user.is_authenticated():
        _add_to_header(response, 'Cache-Control', 'no-store')
        _add_to_header(response, 'Cache-Control', 'no-cache')
        _add_to_header(response, 'Pragma', 'no-cache')
    return response

class NoCacheIfAuthenticatedMiddleware(object):
    def process_response(self, request, response):
        try:
            return _nocache_if_auth(request, response)
        except:
            return response

Oh, and an annoying note: it’s still possible for firefox to keep an authenticated page cached, I can get that to happen with a sequence of Back and Reloads. Maybe that’s because the Back button is trying to respect history rather than the cache? Oh well, I told you not to mistake this for a security fix.

Advertisements

Tags: ,

4 Responses to “Authentication and Browser Caching in Django, part II”

  1. James Bennett Says:

    This feels like it’s largely duplicating Django’s built-in ‘never_cache’ decorator… 😉

  2. mrlauer Says:

    This is pretty similar to the built-in decorator, but with two differences that I care about:

    * It’s middleware, not a decorator, so nothing has to be done per-view.
    * This is conditional on whether there’s a user logged in (as is the built-in cache middleware if CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set).

    Not to say I’m not missing something I should be using in the built-in framework…

  3. Luke Says:

    Another solution would be to add this to your base template:

    {% if user.is_authenticated %}

    {% endif %}

  4. Luke Says:

    Looks like the html tags weren’t allowed in the previous post.. but, I just had the no-cache meta tags inside the is_authenticated condition.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: