Set session key - django

How can I change the session key used by a django session? I'd like to support multiple simultaneous sessions in the same browser by specifying an ID in the URL and then incorporating that ID in the session key.
I've tried simply:
request.session.session_key += key
But I get an AttributeError saying that I "can't set attribute".

You could achieve this by writing your own SessionMiddleware (based of Django's django.contrib.sessions.middleware.SessionMiddleware) which supports looking up and storing multiple seperate sessions linked to the same user.
Have a look at the source of the SessionMiddlware, it seems that it quite simply gets a cookie by the name of 'sessionid' (by default), creates a enging.SessionStore instance and stores it as a 'session' attribute of the request instance.
You could theoretically do the same only getting/setting your own cookie names (i.e postfixed with the identifier passed in the request params), and store it in your own attribute (i.e request.custom_sessions) and then be able to use it wherever a request instance is available.

Related

KeyError: 'user_available'

I am trying to implement a check that if a user is available then render a specific template. I am using this condition if session['user_available']: where session is imported from flask. But I am getting KeyError: 'user_available' error. If this method is deprecated then what is the updated code for assessing the availability of current user using session.
At the time of the request, the key-value pair does not exist in the session. This results in the KeyError.
Much of this session is to be used like a dict. So you can query if a key-value pair exists within the session. This should assume that even if the key is not part of the session, no KeyError is thrown.
if 'user_available' in session and session['user_available']:
# The key is present in the session and the value is set.

In Django, what would be the proper way to persist session information?

I am designing a REST app in django, which I intend people to use without a browser (just direct API calls with curl or whatnot). I have several different views where I want to pull in information about the session based on values that may have been a acquired from previous calls to other views. It seems that every time a view is called the "request" object passed in is an entirely new session, so I'm wondering how I can persist values the "correct" way?
Example code:
def login(request):
...
##I want to assign a token value to this session that is persisted to the entity requesting it
request.session['token'] = response.json()['auth']
...
def grabSomeValues(request):
...
##I want to grab the session token value in here but of course the request object in the case is a completely new one that does not have that token value it seems
print(request.session['token']
....
I think Middleware would help you.
The session framework lets you store and retrieve arbitrary data on a per-site-visitor basis.
https://docs.djangoproject.com/en/2.2/topics/http/sessions/

How to invalidate all users from all browsers and machines in tornado

After successful authentication the user I am setting following -
self.set_secure_cookie('user', str(user.id), 1)
self.set_secure_cookie('expires_days', 1)
self.set_secure_cookie('max_age_days', 1)
Now the requirement is to logout all users on a specific action. For this I am trying -
self.clear_all_cookies()
but this is only logging out the current user. Not other users logged-in from other machines or browsers.
I am using tornado 4.3 and Python 2.7
Any way I this can be acheived?
You can't delete the cookies of all "connected" users with in one go as each request is handled separately, but you can try invalidating them so they can be deleted on their next request.
A simple solution would be to store a cookies_valid_from timestamp in your Application and on user login set a created_on timestamp cookie for the user. Your get_current_user() function could look like this:
def get_current_user(self):
if self.get_secure_cookie("created_on") < self.application.cookies_valid_from:
self.clear_all_cookies()
return None
return self.get_secure_cookie("user")
The specific "log out all users" action you mention can simply update the cookies_valid_from timestamp to the current time.
To invalidate absolutely everything, you can simply change your cookie secret. All existing cookies will be ignored and you can begin issuing new ones. But if you need something more nuanced than that, you'll have to design it in to your authentication protocol. For example, don't just store the user ID in the cookie, store a session ID and keep track of the currently-valid session IDs in a database or cache. Then you can invalidate user sessions by deleting their IDs from the database.

A signal that a session has been created ? [for anonymous user]

I can't seem to find the the signal that tie with a 'session created' .
I'm aware of auth signals , but what i want is to populate a session variable for anonymous users.
What am i missing ?
Thanks in Advance
To store a session variable for anonymous users, you can do something as simple as request.session['something'] = True (or whatever value you want) in the appropriate view. And if you're trying to see if you've seen an anonymous user before, you can just test for the existence of the 'something' key.
Under the hood, django handles cookie setting and creates a session for an anonymous user if you modify the session variable. If the anonymous user already has a session, it simply records the modified state.
Take a look at the session docs: https://docs.djangoproject.com/en/dev/topics/http/sessions/ for more details. It's pretty sophisticated.
Finally, don't forget to clean expired sessions periodically with ./manage.py clearsessions if sessions are stored in a persistent store.

Editing session of another user in Django

How can I do this
request.session['key'] = 'value'
for the user which user_id is 47?
Keep in mind that I'm not currently logged in with that user, I want to do it in shell.
See the section of the Session docs entitled "Using sessions out of views".
The problem though is that Django doesn't store the user with the session (by design, for security purposes). So the only way to retrieve a session is through it's key. That key is stored with the user's client and passed to the server to associate the session with the logged in user. In other words, you're going to have a hard time determining which session belongs to which user.
More to the point, the session data is actually encrypted in the database as well, so there's not even any way to query directly for the user id stored in it. The following will work, but you'll have to query each session one by one to get the right user. Depending on how many sessions your database currently has, this could be extremely expensive. Mark as USE AT YOUR OWN RISK
from django.contrib.sessions.models import Session
from django.contrib.sessions.backends.db import SessionStore
for session in Session.objects.all():
data = SessionStore().decode(session.session_data)
if data.get('_auth_user_id') == user_id_you_want:
user_session = SessionStore(session_key=session.session_key)
# you can modify the session data here like normal, then:
user_session.save()
The answer depends entirely on the session storage/engine you're using.
So, the generic answer would be: Wherever the session is being stored, modify it there.
For the database backend: UPDATE django_session SET session_data=[whatever] WHERE session_key=[whatever];
You'll also need the session key and the AES key stored in the client browser.
Alternatively, send them to a controller that updates the session.