How do I track sessions in Django even after a user has logged in or out? I am using Django authentication.
For example, a user lands on the main page, and maybe follows a few links on my site. Then he logs in. Logs out. Follows some links. I want to track that this is the same user, or at least someone using the same browser session.
I am currently tracking
request.user.id
which is, of course, specific for a logged in user.
I thought I could use
request.session.session_key
to track the session, but the session_key changes when the user logs in and again when he logs out.
(What I really want to know is whether the person who lands on my page also logs in / signs up.)
Don't rely on the session cookie for this (because indeed, Django automatically rotates it across login / logouts — mainly to prevent session fixation attacks).
Instead, just create your own cookie, and track users that way.
Related
I am creating a saas, software as a service site with django.
Due to the project requirements the users are inside schemas/tenants, for that im using the fantastic django-tenant-schemas app, one user can have accounts inside different schemas (they share username and password) ... i want to let the user move throught the different schemas they are in more or less freely ... for that i have created a view where the user can select on what schema he wants to be on.
When i use an application wide cookie session that is when i have the cookie setting as ".domain.ext" (django documentation) that works fine but its NOT the behaviour we really want for our application.
What we really need is to be able to have different versions of the app on different browser tabs.
So we have to set the cookie configuration to "domain.ext", then everything breaks because the original view is on one tenant and the next view (where the just logged user really belongs) is inside other tenant then the old cookie is deleted.
So the question is how can i programmatically set the cookie correctly on the new view so the user that really belongs to that tenat is still authenticated.
Or is there any alternative approach we could use for that? Any examples?
EDIT TO CLARIFY as demanded:
Person A belongs to 2 schemas SH1 and SH2 on both of them he has the same username and password.
On every password change the password hash is replicated on all the schemas they belong to so they dont have to remember specific passwords or usernames.
When the person is logged on SH1 the url will be sh1.domain.com when he is logged on SH2 the url will be sh2.domain.com
So lets say the person is now logged on schema SH1, he decides to switch to schema SH2, to be able to do that i need the user to still been authenticated so that view has to be on the SH1 schema, but then its redirected to the new schema force authenticating the user but since the cookie is set as domain specific (default django behaviour) when the user lands on the next url sh1.domain.com/whatever the previous cookie is deleted and thus he has to log in again to be able to access.
If I'm understanding correctly, you want the ability to have the behavior of a cross-domain cookie, but without actually using a cross-domain cookie.
The immediate answer that comes to mind is "well, use a cross-domain cookie". This is pretty much the vanilla example of a situation where you'd want to use use a cross-domain cookie. Engineering a complex solution so that you can avoid using the simple solution never ends well :-) Unless there's some other constraint in play that you haven't revealed, I'd start by questioning whether you shouldn't just be doing this the easy way.
However, assuming there is a good reason (and, frankly, I'd be interested to know what that is), the problem you're going to face is that browser security is essentially trying to stop you doing exactly what you're proposing. You want to know, from domain SH2, whether something has happened to a cookie set on domain SH1. That's exactly the situation that cookie security policies are designed to prevent.
The only way you're going to be able to work around this is to have a third party that can share knowledge. When user A logs into SH1, you do password authentication as normal - but you also post a flag somewhere that says "User A is now on SH1". When A logs into SH2, you post the corresponding flag. If A goes back to SH1, you check against the central source of truth, discover that they're currently on SH2, and force a login.
You probably could do this by manipulating cookies and session keys, but I suspect an easier way would be to use an Authentication backend. What you'll be writing is an authentication backend that is very similar to Django's own backend - except that it will be making checks of cross-domain login status against the central source of truth.
How you implement that "source of truth" is up to you - an in memory cache, database table, or any other source of data will do. The key idea is that you're not trying to rewrite cookies so that the same cookie works on every site - you're keeping each site's cookies independent, but using Django's authentication infrastructure to keep the cookies synchronised as a user moves between domains.
I have a webapp that allows authenticated as well as anonymous users to start entering some form data. If a user is happy with his/her input, he/she can save that form to the server. This is a very similar problem to a shopping cart application that does not require login until checkout time.
For the authenticated user, implementing a save button is trivial. However for the anonymous user, the form data need to be stored somewhere while authentication is taking place, then correctly retrieved after logged in. Can someone please suggest some general strategies to go about this?
I found this link that is promising but I want to be thorough about this topic.
I think the correct way of doing this is to use django sessions. Basically each user (anonymousUser included) has a session during its stay on the website (or even more).
If you have a form that you want to store for a specific session, you can do it by using
request.session['myform'] = form
you get it by
request.session['myform']
and you can delete it using
del request.session['myform']
Basically Django pickles a dictionary of the session and saves it in a place (typically the database, but can be on other place as explained in django sessions).
I have build a Facebook-app that needs to post to the users wall in certain situations. I've come a long way in doing this: it works perfectly, even when the user is not logged in. However, I need to post to the user's wall on behalf of the app, not the user himself. The reason is that posting as the user will not trigger a notification.
Does anybody know how to do this?
This is not possible; apps cannot post to the profiles of users - if you want someone to come back to your app, you could use a Request which will increment the counter on the user's bookmark for your app, but it's not possible to post to a user's profile 'from' a page or application
I understand request.sessions dictionary and how to use this.
However, it appears that values set using request.sessions is only valid while the user is logged in.
I need to set a persistent cookie that lasts for a fixed time period and not dependent on whether the user is logged in or not.
What I would like is to store a value for an anonymous visitor to my site, and also retrieve that same value if that user creates an account and logs into the site. The value should be retriEvable if the user logs in or logs out between sessions.
Any code examples on this?
Sessions should work fine for anonymous users. What's happening to make you think it only works for authenticated users?
Aside from that, maybe take a look at deferred registration which may do what you're looking for, http://tartarus.org/james/diary/2009/07/24/implementing-deferred-registration-with-django .
As Rolo says, Sessions work when for anonymous users, but When you use the auth.logout method the session is completely wiped. In your logout view, you could call auth.logout, then add whatever data you wish to persist back into the session.
On logging in, the request's session key changes.
This makes it hard to use sessions, for activities that should persist across login, such as, say a shopping cart, where the login is prompted only while check out.
What is the best way to implement such a cart, which persists across login. One solution would be to have a table with session keys and products and on login, associate the user to it.
It could be simpler, I feel, particularly, all you want is to persist just a single post request.
This used to be a feature of Django, but it was removed, because it was a security issue. If you're going to implement something similar, you'd be wise to understand the security implications of it (which I don't, I just know there were issues).
I think the feature used to work by pickling the post data, and storing it in a hidden field of the login form.
The relevant announcement is here, and the code change is here.