Django appends to host instead of website name - django

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?

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?

Unable to login to Django admin after changing SESSION_COOKIE_NAME

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?

django admin login suddenly demanding csrf token

I was logging into my django admin console easily a few minutes ago. I must have changed something somewhere that caused this error when logging in as superuser:
Forbidden (403)
CSRF verification failed. Request aborted.
This error caught me off guard as I was logging in all night. Why would I suddenly need a csrf token for admin login? You would think the sign in form already has that. This is my admin.py:
from django.contrib import admin
from accounts.models import Image, Category, UserProfile
class ImageAdmin(admin.ModelAdmin):
list_display = ["__unicode__", "title", "created"]
admin.site.register(Image, GenericImageAdmin)
class CategoryAdmin(admin.ModelAdmin):
list_display = ["category"]
admin.site.register(Category, CategoryAdmin)
admin.site.register(UserProfile)
for new users facing this issue after upgrading to Django +4.0 you need to add CSRF_TRUSTED_ORIGINS=['https://*.YOUR_DOMAIN.COM'] to settings.py
thanks to the below answer:
https://stackoverflow.com/a/70326426/2259546
Admin login normally does require a csrf token, but that's normally all taken care for you.
Check your browser's cookies to see if there is a csrf token present
Try clearing cookies and refreshing
If you are using Django 4.0, you may to add this line to your settings.py file: CSRF_TRUSTED_ORIGINS = ['https://*.mydomain.com','https://*.127.0.0.1'] (making the appropriate changes). In 4.0, they started checking the origin header unlike in previous versions. Thanks to this answer for suggesting this solution.
Check to make sure you have django.middleware.csrf.CsrfViewMiddleware in your middleware
Check that you're either on https or you have CSRF_COOKIE_SECURE=False (which is the default) in settings, otherwise your csrf cookie exists but won't be sent. Purge your cookies after changing CSRF_COOKIE_SECURE.
This error was appearing for me when I had not set CSRF_COOKIE_DOMAIN in my settings_local but it was set in my main settings.py.
In my case I set it to the local host eg
CSRF_COOKIE_DOMAIN = '127.0.0.1'
Add a csrf token to your context in the login view and in your template add in the hidden div for the csrf token. Ensure you have django.middleware.csrf.CsrfViewMiddleware in the middleware section in your settings.py.
Then add #csrf_protect to your views to do with login. It is also possible you tried to login with incorrect credentials - you need #csrf_protect on the logout view in your app's views.py you call on the appropriate uri for login/logout etc. in urls.py also. My logout simply calls logout(request) then calls HttpResponseRedirect('') which is probably not perfect but it does me for my needs for now.
As a security measure, I had CSRF_COOKIE_SECURE = True in my settings. Trying to log into admin via localhost where there isn't HTTPS threw the forbidden error.
Set it to False to get it working on localhost
This could also happen when you are already logged in into your website hosted on a url different than admin. And then try to login into your admin panel in a new tab.
Try to open the admin panel in a different window.
Try opening your site in incognito mode.
There is a good chance that it could be your browser cookie, the above test will iron out that possibility.
I used to have the same problem every time when I was using my default environment, and then using a virtual environment worked for me. It works every time. If you don't know how to create a virtual environment, here's how you do it:
Just create a virtual environment in your project's directory by
running the command virtualenv theNameYouWannaGiveYourEnvironment.
Then activate your virtual environment by using
theNameYouWannaGiveYourEnvironment/bin/activate(on Linux, I think it works for Mac Os too, but it's different for Windows).
After that, just install Django by pip install django and all the other requirements for your application to run.
Alternatively, you can also use Anaconda to create your virtual environment and install all your requirements. Just refer to this documentation if you wanna use anaconda: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html
If you're on Production, make sure that your URL is configured inside ALLOWED_HOST on settings.py
In my case it was solved by changing the setting:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
to
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'http')

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?

Auto logout using sessions in Django (outside views)

I'm trying to build a auto-logout function in a Django application.
Basically, with each request to the site I want to set the current timestamp in the session (if not set), and then checking that value with the current time. If the difference is too great, it should redirect to logout.
Is there a easy way to set the session on each request without adding a function to each of my views?
I know it's possible to use sessions outside views, but then I have to supply the session_key, and I'm not sure where I should get it from, or generate it myself.
I'm not sure what timestamp you are comparing with what here, or why.
The usual way to manage auto-logout is to simply set a short expiry on the session cookie, via the SESSION_COOKIE_AGE setting. If the cookie expires, the user will automatically be redirected to the login page if they try and access a page that requires authentication.