[Fixed]-Different sessions for admin and applications in Django

10👍

The way I have solved this in the past is to have 2 different urls. www.example.com and admin.example.com. As the sessions are stored in cookies, and the cookies being domain specific you can use both at the same time.

7👍

Just wanted to encourage the usage of Bernhard Vallant’s proposed solution.
It takes 10minutes to implement and test.
Just grab the SessionMiddleware implementation make your own version of it replacing the settings.SESSION_COOKIE_NAME depending the request path starts with admin url or not
and replace the
django.contrib.sessions.middleware.SessionMiddleware middleware with your new one in your settings.py

import time
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date
from django.utils.importlib import import_module
class AdminCookieSessionMiddleware(object):

    def cookie_name(self, request):
        if request.path.startswith(u'/admin'):
            return settings.ADMIN_SESSION_COOKIE_NAME
        return settings.SESSION_COOKIE_NAME

    def process_request(self, request):
        engine = import_module(settings.SESSION_ENGINE)
        session_key = request.COOKIES.get(self.cookie_name(request), None)
        request.session = engine.SessionStore(session_key)

    def process_response(self, request, response):
        """
        If request.session was modified, or if the configuration is to save the
        session every time, save the changes and set a session cookie.
        """
        try:
            accessed = request.session.accessed
            modified = request.session.modified
        except AttributeError:
            pass
        else:
            if accessed:
                patch_vary_headers(response, ('Cookie',))
            if modified or settings.SESSION_SAVE_EVERY_REQUEST:
                if request.session.get_expire_at_browser_close():
                    max_age = None
                    expires = None
                else:
                    max_age = request.session.get_expiry_age()
                    expires_time = time.time() + max_age
                    expires = cookie_date(expires_time)
                # Save the session data and refresh the client cookie.
                # Skip session save for 500 responses, refs #3881.
                if response.status_code != 500:
                    request.session.save()
                    response.set_cookie(self.cookie_name(request),
                            request.session.session_key, max_age=max_age,
                            expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
                            path=settings.SESSION_COOKIE_PATH,
                            secure=settings.SESSION_COOKIE_SECURE or None,
                            httponly=settings.SESSION_COOKIE_HTTPONLY or None)
        return response

and in settings.py

MIDDLEWARE_CLASSES = (
...
#'django.contrib.sessions.middleware.SessionMiddleware',
'path.to.your.AdminCookieSessionMiddleware',
... )
ADMIN_SESSION_COOKIE_NAME = 'somethingDifferentThanSESSION_COOKIE_NAME'

1👍

You can also achieve this with two (very slightly different) settings files, each having a different session key name:

In settings_app.py:

SESSION_COOKIE_NAME = 'mysite_app'

In settings_admin.py:

SESSION_COOKIE_NAME = 'mysite_admin'

I’ve found it useful to have different urls.py files too; while not strictly necessary, it does aid with separation of concerns.

👤tbm

0👍

I had a similar problem with Django REST Framework, so my answer is dedicated to those who find themselves in the same situation as me.

Most likely, if you encounter a similar problem using DRF, authorization using sessions is allowed in your config. This is convenient when testing endpoints, but in most cases, in production you won’t need it, just like BrowsableAPI in principle.

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # UNCOMMENT IF YOU USE BROWSABLEAPI
        # 'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_RENDERER_CLASSES': (
        # UNCOMMENT IF YOU USE BROWSABLEAPI
        # 'rest_framework.renderers.BrowsableAPIRenderer',
        'rest_framework.renderers.JSONRenderer',
    ),
}

Leave a comment