4
votes

I would like to use Custom Django Middleware (Django 1.9) to check whether or not an anonymous user has accepted a site's terms & conditions - I'll show the user a dialog if they've not yet clicked 'Agree'.

I have no need to store this in the database and would prefer to simply use a Cookie. I have the following in settings.py:

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...
    'myapp.middleware.app_custom_middleware.TermsMiddleware',]

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'

I'm then trying something very rudimentary in TermsMiddleware - here I'm deliberately trying to modify the request and the response just to try to get it to work:

class TermsMiddleware(object):

    def process_request(self, request):
        request.session['myCookieKey'] = 'myCookieValue'
        request.session.save()
        return

    def process_response(self, request, response):
        request.session['myCookieKey'] = 'myCookieValue'
        request.session.save()
        return response

If I inspect the response in the browser, I see that myCookieKey isn't being set, so I think I've misunderstood how this should be written.

Can I manipulate the session within middleware like this, having it take effect in the cookie sent in the response Django was going to send anyway? The documentation makes it sound like I should be able to:

It should return either None or an HttpResponse object. If it returns None, Django will continue processing this request, executing any other process_request() middleware, then, process_view() middleware, and finally, the appropriate view. If it returns an HttpResponse object, Django won’t bother calling any other request, view or exception middleware, or the appropriate view; it’ll apply response middleware to that HttpResponse, and return the result.

I've also seen the note in the documentation to use SessionStore() when outside of a view function. In theory I don't think I should need to do that here because I've got access to request (and response). I tried it anyway, and I still couldn't get it to work.

Help much appreciated!

1

1 Answers

3
votes

The thing you've misunderstood is the relationship between the session and the cookies.

You can't set arbitrary cookies by modifying the session. The session is a collection of data, usually stored in the db or a file, and the only cookie is the one that contains the session key for the current user.

You certainly can modify the session in middleware, but wherever you do so, you shouldn't expect to see a cookie being set.

(Separately, you should never call double underscore methods like __setitem__ directly. The session is accessed via a dict-like interface: request.session['foo'] = 'bar'.)