How Can I retain session information once a user registers (Django)? - django

When a new user is created, I want to retain some of the information in their session
e.g. things a user has stored in their session I want to use once they have registered (or logged in).
I would use either a post_save signal on the user model (or an auth login signal), but it appears that the signals don't put the request, or session into the signal sent. It also seems I can't easily get the session from just the user.
I'm using Django 1.4
Edit: let me give an example.
The problem boils down to this - I may want to retain information for a user's activities before they login, but where do I store this information before they login? A good place would be a session (or I could link the data held in a db to the session, using the session a little like a makeshift user).
In any case, until they login, I can simply use their session like a user credential, and store information that persists so long as their cookie does (how else can could I reliably track an anonymous user?).
But once they register (or log-in), I want to move that information from the session, into the account properly. One good reason is that it would make sense to delete data from anonymous users periodically, whereas registered user's data would be persisted.
To do this I simply want access to the session (could be via the request) from a handler to the new-user signal, so I can make a one-off transfer from data in the session. But the new-user signal doesn't hold the session (or request).

If you're using django.contrib.sessions and django.contrib.auth for the job, the session data should be retained automatically after login.
Moreover, the user_logged_in signal is sent along with request actually.
Edit:
So use user_logged_in signal. It carries request. Pick some specific key to store unauthenticated user's data (e.g. "_anonymous_data"). If that key is set on request.session while handeling signal, simply rewrite data on request.user.get_profile() object, call save and del request.session["_anonymous_data"].
The code to retreive it could look something like:
if request.user.is_authenticated():
user_data = request.user.get_profile()
else:
user_data = requerst.session["_anonymous_data"]
It's only a scratch of course. You don't want to hardcode session keys or write such logic in views. If you need it application wide, embed it in some abstraction class which takes request in __init__.

you could try using sessions:
https://docs.djangoproject.com/en/dev/topics/http/sessions/?from=olddocs

Related

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/

django-auth: login with user uuid and limit permissions

I'm trying to create a kind of quick response form where a user does not need to login but is identified with his uuid (in the url). Moreover i need to restrict his permissions for this session so that he only could to a few things.
User gets url with UUID and ID of event (Where he can response)
User clicks on link and response page opens
User is identified via uuid
With the id of the event the event response form is generated
User can chose options and submit the form
Normally there are multiple other options (e.g. in the menue) available but these should only be accessible if user identifies with his username and password.
Of course i could write a special view but is there a more elegant way where i could reuse my existing view for the response?
First you'll want to use the UUID to trigger the login.
How you approach this will depend on whether you mind using a specific login url/view or you want people to arrive directly at the intended url/view (just with the UUID parameter). If you use a specific view you'll check the UUID, (presumably mark it as used/expired), then login the user. Alternatively for the UUID to checked and have users login via any url/view, you'll want a to use a custom middleware that's placed ahead of AuthenticationMiddleware in your middleware settings. In each case, once you have the logged in the user, you'll want to store in session some sort of flag to indicate they've auth'd via a temporary login UUID.
Now that you've authenticated and logged in the user via the UUID, it's time to serve them the view. At this point in your View you'll check for presence of the flag in the user session to determine their permissions.
You could go further and create another middleware class to encapsulate the session lookups and add a property, say "is_auth_temporary", to the request.User object that is a sibling to the is_anonymous and is_authenticated property.

How to access session data in a signal handler?

Whenever a visitor who is not a user adds content to my site I just create a dummy user account and store it's id in the session of that visitor.
Now when a visitor finally logs in using Facebook, Google or any other OAuth I want to merge the dummy user with the real user account. I figure a good way would be to catch the login signal. But in order to find the previous dummy user account I need to enter the session data. How can I get to it from within the handler?
If it's not possible than how to approach this problem?
Please note that I want to be able to use various login apps like django-social-auth so I need a solution that hooks in very clean.
Thank you for your time.
The login signal includes the current request as one of it's parameters:
https://docs.djangoproject.com/en/1.7/ref/contrib/auth/#module-django.contrib.auth.signals
Something like:
#receiver(signal=user_logged_in)
def merge_accounts(sender, request, user, **kwargs):
user.update_details_from(request.session['your-dummy-data'])

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.