Cache, Session and Auth Middleware and Vary: Cookie

471 views
Skip to first unread message

Tamas Szabo

unread,
Mar 3, 2010, 4:50:22 AM3/3/10
to django-d...@googlegroups.com
Hi,

I've just enabled caching for a Django application and it works great, but there is a small problem.

As you know, Session middleware adds a Vary: Cookie header to the response and it is smart enough to do that only if the session has been accessed.

This is all good, but the problem is that I have @login_required on the majority of my views and although they don't touch the session at all the Vary: Cookie header will be added.
This is because the decorator has to get the user from the session so the session middleware sees that the session has been accessed and sets the header.

So a simple view like the one below will set the Vary: Cookie header, although the result isn't user specific at all and this will prevent caching.

@login_required
def some_view(request)
    return HttpResponse('Some text')

The ideal solution would probably be to being able to access the session without making the session dirty from framework code and then the auth code could do just that.

Another possibility is to set the accessed flag back to False from the auth code after accessing the user in the session, but I think that needs more additional code, because request.user could be accessed from the view and I don't think that will set session.accessed = True

Another possibility is to say that this is not a problem / can't be easily fixed, but then we probably need a new decorator, so we can mark views as @never_varies_on_cookie, because currently I don't think that we can avoid having the Cookie added to the Vary header by SessionMiddlewar.

I thought I send an email to django-dev before raising a ticket to get some other opinions on the issue.

Thanks,

Tamas

Tom Evans

unread,
Mar 3, 2010, 5:10:09 AM3/3/10
to django-d...@googlegroups.com

If the view is login required, then you must send 'Vary: cookie',
there is no option. Consider what would happen if you did not vary on
the cookie:

Logged in user accesses the page via a caching proxy
Returned page is cacheable, no Vary header
Proxy stores page in cache
Not logged on user requests the page via the proxy
Proxy retrieves cached, logged on version of the page and delivers it
to not logged on user

Cheers

Tom

Tamas Szabo

unread,
Mar 3, 2010, 8:41:57 PM3/3/10
to django-d...@googlegroups.com
Hi Tom,


If the view is login required, then you must send 'Vary: cookie',
there is no option. Consider what would happen if you did not vary on
the cookie:

Logged in user accesses the page via a caching proxy
Returned page is cacheable, no Vary header
Proxy stores page in cache
Not logged on user requests the page via the proxy
Proxy retrieves cached, logged on version of the page and delivers it
to not logged on user

Cheers

Tom


Yes, you are right, I haven't considered intermediary proxy caches.
I was more concerned about what happens on the browser, as it seems that Firefox handles the Vary: Cookie as Vary: * (ie. it doesn't use its cache even if the session cookie is the same).
So, it seems that if Vary: Cookie is set, the only place I can benefit from caching is on the server-side using Django's cache middleware.
That works fine, but the cache is per-user and t doesn't seem that I can tell the caching middleware that I don't want that.

It looks like if you have a webapp that requires login for all the pages, for pages that aren't user specific all you can do currently is to cache manually in the view.
Is this true?

Ideally, I would like to be able to use the caching middleware in this scenario by using only configuration + decorators.
Does this makes sense?

Thanks,

Tamas

Reply all
Reply to author
Forward
0 new messages