Question

I've built a small custom middleware to log out the user and flush the session conditionally. I'd expect the current request to have the user logged out. However, for the request/response currently being processed, I still have a full response as if the user hadn't been logged out and the session is perfectly available (unexpected). All subsequent request don't have the session anymore (as expected).

Digging down in the SessionStore it appears that the session is just a model and is restored further in the request just by the session key from the cookie the browser has sent. Additionally, the logout() seems to be ineffective because of that too.

How can I actually log out a user in the middleware? Do I have to manually delete the session from the database? That seems so painful.

In myapp/middleware.py:

from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.auth import logout

class SomeSessionMiddleware(SessionMiddleware):

def process_response(self, request, response):
    if somecondition:
        logout(request)
        request.session.flush()
        print "flushing session, log out user" # I see this.
    # And just call the super class
    return super(SomeSessionMiddleware, self).process_response(request, response)

In settings.py:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    #'django.contrib.sessions.middleware.SessionMiddleware',
    'myapp.middleware.SomeSessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
Was it helpful?

Solution

Page is already rendered there

Using process_response, this is called very late in rendering the response. I need to use process_request instead to perform this. Additionally, note that the middlewares defined are called in reverse order for the response.

This will work:

from django.contrib.sessions.middleware import SessionMiddleware

class SomeSessionMiddleware(SessionMiddleware):
def process_request(self, request):
    if somecondition:
        request.session.flush()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top