Unable to login to Django admin after changing SESSION_COOKIE_NAME - django

I want to change the SESSION_COOKIE_DOMAIN because it's set incorrectly on a production server. Due to this, I also need to change the SESSION_COOKIE_NAME to something else. Otherwise there'll be two cookies with the same name and different domains on the users side, because it's already in production. With these two cookies, the user will have trouble logging in.
This would normally be fine, but now the problem.
Just after I changed the SESSION_COOKIE_NAME (so I haven't even changed the SESSION_COOKIE_DOMAIN yet), I am unable to login into the admin console. I can see the cookie with the new name being set. The application itself has no problems and users can login without problems, which is strange because it's the same authentication.
What I've tried:
Deleting all session on the server site
Private mode
Other Browser
Flushing all possible caches on the server but might have mist one.
Checking for hardcoded session names, but there are not.
What else could I possibly check? If I set the SESSION_COOKIE_NAME back to what it was, I can log in again. This issue only happens on the production server; not locally, and on not on the test server, which makes it hard to test.
Any ideas?

Related

I changed the session cookie name in my django project and I am unable to login

I want to change the SESSION_COOKIE_DOMAIN because it's set incorrectly on a production server. Due to this, I also need to change the SESSION_COOKIE_NAME to something else. Otherwise, there'll be two cookies with the same name and different domains on the user's side, because it's already in production. With these two cookies, the user will have trouble logging in.
This would normally be fine, but now the problem.
Just after I changed the SESSION_COOKIE_NAME (so I haven't even changed the SESSION_COOKIE_DOMAIN yet), I am unable to login into the admin console. I can see the cookie with the new name being set. The application itself has no problems and users can login without problems, which is strange because it's the same authentication.
What I've tried:
Deleting all sessions on the server site
Private mode
Other Browser
Flushing all possible caches on the server but might have missed one.
Checking for hardcoded session names, but there are not.
What else could I possibly check? If I set the SESSION_COOKIE_NAME back to what it was, I can log in again. This issue only happens on the production server; not locally, and not on the test server, which makes it hard to test.
Any ideas?

Django appends to host instead of website name

I'm trying to use the #user_passes_test(function, login_url) decorator on a production server, but it seems login_url is not getting appended as host/mysitename/login_url but only as host/login_url. Everything works correctly from a local machine, though. The problem only appears when I'm trying to run it on the server. I have already set LOGIN_URL in the settings.pyfile, but the problem is that I need to send the user to a different login page, since they need to be authenticated via LDAP.
Changing login_url to /mysitename/login_url works, but isn't there a better, more elegant solution to this?

Django Login/Session Not Sticking

After my site has been up and running for a while in production, I suddenly have a problem with my users loging into it.
I have protected certain views/pages with the login_required decorator and I am also using the django admin.
When an anonymous user hits any of these pages, he is redirected to the login page.
When this anonymous user adds its credentials, the POST request is successful and he is redirected to the inital page. At the same time, the user gets a new sessionid (as expected)
However, now the results get very unreliable. When pressing reload or when navigating to other pages (that require a login), either of the 2 outcomes might happen:
a) The user is identified and the page is displayed correctly
b) The user is redirect to the login page.
I have checked the content of the session via the shell, and nothing is changing there.
The production site is served via a load balancer and 8 application servers. Even stranger: if I test the same code (with the same settings) on a test server, that is not load balanced and basically has not traffic, everything is working fine.
I am running Django 1.6 on Ubuntu with Apache and mod_wsgi in daemon mode behind SSL and I am using the Session database backend. I am using django-allauth.account for account management/login. My Session settings are like this:
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_AGE = 60*60*24
SESSION_COOKIE_SECURE = True
UPDATE
To get some more debug information, I have created this Middleware:
from django.conf import settings
class SessionDebugMiddleware(object):
def process_response(self, request, response):
session = request.session
user = getattr(request, 'user', None)
if user:
user=user.id
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
response['X-Meta-Requ'] = '{0},{1},{2},{3}'.format(session_key, session.get('_auth_user_id'), session.get('_auth_user_backend','---'), user)
return response
If I hit the refresh button 10 times,
8 times I will get this header:
igv0xshezhdxh50kks9x00r0l67mx0sk,None,---,None
2 times I will get this header: X-Meta-Requ:igv0xshezhdxh50kks9x00r0l67mx0sk,330619,django.contrib.auth.backends.ModelBackend,330619
It seems be be random and does not follow any logic.
So I have the following questions/ideas?
Can this be related to loadbalancing in anyway? My understanding was that Django does not need sticky sessions, when the DB session backend is used.
Can this be related to a threading issue?
Can this be related to high load?
Can this be related to a decoding issue: https://github.com/django/django/blob/master/django/contrib/sessions/backends/base.py#L83. But why should that decoding issue not be consistent. And I have not found any log entries that refer to "Session data corrupted".
Any other hints are welcome.
Just in case someone is having this issue, it can also be caused by SECRET_KEY definitions not being consistent.
I had mine generated in the settings file (a bad decision).
It was fine in development mode, but once the application was served by WSGI, multiple instances were created, each with different keys.
This causes the mixup in the hash, and the corrupt session to be reported.
I think you have problem because of highload or error in your code (maybe you just rebuild session in your application anywhere and forget about it :)
Please try to read info from database with your session key to be sure session data exists.
If data exists but not loaded to session - this mean you have troubles with session processing. If data doesn't exists, but it present in past because you got 2 times right session data, this mean you have problems with session storage (maybe because of highload your database lose sessions data). Do you have database replication?
Also which session backend you use? Just a DB or Cached_Db?

Secure django session cookies are overriden when a non-secure page is used

Setting SESSION_COOKIE_SECURE = True in Django tells the browser to only send the session cookie over SSL. However, if an authenticated user navigates from a secure page to a non-secure page the session middleware will not know about the secure session (since the cookie won't be sent) and will set a new session cookie. The effect is that the user is then logged out, and needs to log in again.
For example, a user might edit something in the secure admin, click "view on site", is taken to a non-ssl page, then clicks back, only to find that their session has been overwritten, and is no longer authenticated.
I'm just wondering what the preferred approach would be to solve this issue.
As I can see, there are the following solutions:
Use different (sub)domains for the secure / non-secure parts of the site. Force everything on the ssl domain to be ssl. (I know this would probably be the preferred option, but is currently not an option)
Use different django projects (and different session cookie names) for the secure / non-secure parts of the site. Use nginx to proxy to appropriate django project.
Create a custom middleware based on django.contrib.sessions.middleware.SessionMiddleware that manually handles sessions differently depending on secure / non-secure. Perhaps even check whether the url is an admin url, and use a different cookie name and cookie path.
Set SESSION_SAVE_EVERY_REQUEST = False and hope that the user doesn't navigate to pages that use cookies.

Django Sessions getting dropped when redirected from another domain

When a user visits my domain, a sessionid is issued by django. When he tries to do Oauth with Facebook, he clicks a button on my site which redirects to Facebook.com. Facebook redirects back to my domain, but at this point, the user's session is lost and Django seems to be issuing a new session variable.
I want the dropped session to persist because I must associate the visitor to my site with his Facebook account, but when the session is dropped, the logged in user is logged out.
I have a suspicion that this may be behavior related to django's XSS protection. How do I make the user information persist when the user leaves our site to log in at Facebook?
You might want to confirm that the cookies have the same domain when being created. That can sometimes cause problems. If you are going to the website www.example.com and the OAuth callback points to example.com, then it's possible you have two separate cookies, one for www.example.com and one for example.com
Turn on "Always Ask" on your browser and pay attention to the cookie details. Make sure that the value for the "Host:" field is the same both times.
The fix is entering something like .example.com for SESSION_COOKIE_DOMAIN in your settings.py file.
I've also just discovered that if you have two Django applications running on the same domain, to avoid cookie collision you may wish to set SESSION_COOKIE_NAME differently for each.