We recently changed our cookie domain (settings.SESSION_COOKIE_DOMAIN) from domain.com to .domain.com and this is now preventing Safari users from logging in unless they clear their cookies. The problem seeds to the fact that there's sessionid cookies set for both domains.
Is there a way to clear or ignore the original domain or is the only way to advice users to clear cookies?
To delete a session or any particular key of that session, we can use del. The output will look like this and don't worry if your cookie didn't delete because we use this method only to delete your data in the Django database and not the session ID and cookie itself.
delete_cookie method is used to delete a cookie with a specified value.
Django uses a cookie containing a special session id to identify each browser and its associated session with the site. The actual session data is stored in the site database by default (this is more secure than storing the data in a cookie, where they are more vulnerable to malicious users).
If you want to use a database-backed session, you need to add 'django. contrib. sessions' to your INSTALLED_APPS setting. Once you have configured your installation, run manage.py migrate to install the single database table that stores session data.
This can occur when the SESSION_COOKIE_DOMAIN
setting is modified. (You stated that SESSION_COOKE_PATH
was changed).
The documentation for SESSION_COOKIE_DOMAIN
comes with this warning:
SESSION_COOKIE_DOMAIN
Be cautious when updating this setting on a production site. If you update this setting to enable cross-domain cookies on a site that previously used standard domain cookies, existing user cookies will be set to the old domain. This may result in them being unable to log in as long as these cookies persist.
This would occur if you went from:
SESSION_COOKIE_DOMAIN = None
to
SESSION_COOKIE_DOMAIN = '.domain.com'
As you've stated, there are now two cookies on the client end which will be sent to the server during a request, with both cookies named sessionid
. When Django looks at the cookies, it only has access to a Python dictionary, so it only every sees one sessionid
cookie rather than both that were sent.
I haven't tested this, but some ideas for fixing the problem may be:
Ask the user to delete the appropriate cookies. Depending on the number of users and their skill level, this may not be an reasonable option. Asking them to delete ALL their cookies may be out of the question.
Wait for the old cookies to expire. By default, it appears as though the sessionid
cookie has a 14 day expiry. Once the old session cookies expire, they will no longer be sent with each request, allowing the new sessionid
cookie to take effect.
Change the name of the sessionid
cookie and write a custom Django middleware to handle both old and new sessionid
cookies.
I haven't tested the last point, but it should be possible to change the SESSION_COOKIE_NAME
to something other than sessionid
. Now, this will prevent existing logged in users from using their existing sessionid
cookies, so you'd need to write a custom middleware which was capable of handling both sessionid
cookies (for old cookies) and sessionidnew
cookies for current logons.
Something like this will work:
from django.utils.importlib import import_module
from django.contrib.sessions import middleware
from django.conf import settings
class MySessionMiddleware(middleware.SessionMiddleware):
def process_request(self, request):
engine = import_module(settings.SESSION_ENGINE)
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
if session_key is None:
# Look for old cookie in request for auth purposes.
session_key = request.COOKIES.get('sessionid', None)
request.session = engine.SessionStore(session_key)
You'd have to replace the SessionMiddleware
in settings.py
under MIDDLEWARE_CLASSES
with this new middleware. Eg: Change 'django.contrib.sessions.middleware.SessionMiddleware'
to 'custommiddleware.MySessionMiddleware'
where custommiddleware.py is the file with above code and is present in your project root folder (where manage.py file is present)
Once enough time has passed and you're satisfied that all of the old sessionid
cookies have expired, you could do the reverse and change back to using sessionid
as the preferred cookie name for sessions, eventually removing the specialist code which can handle two different types of sessionid
cookie.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With