views:

2343

answers:

2

I am writing an application where I will be accessing the database from django and from a stand alone application. Both need to do session verification and the session should be the same for both of them. Django has a built in authentication/session verification, which is what I am using, now I need to figure out how to reuse the same session for my stand alone application.

My question is how can I look up a session_key for a particular user?

From what it looks there is nothing that ties together auth_user and django_session

+9  A: 

This is somewhat tricky to do, because not every session is necessarily associated with an authenticated user; Django's session framework supports anonymous sessions as well, and anyone who visits your site will have a session, regardless of whether they're logged in.

This is made trickier still by the fact that the session object itself is serialized -- since Django has no way of knowing which data exactly you want to store, it simply serializes the dictionary of session data into a string (using Python's standard "pickle" module) and stuffs that into your database.

If you have the session key (which will be sent by the user's browser as the cookie value "sessionid"), the easiest way to get at the data is simply to query the Session table for the session with that key, which returns a Session object. You can then call that object's "get_decoded()" method to get the dictionary of session data. If you're not using Django, you can look at the source code (django/contrib/sessions/models.py) to see how the session data is deserialized.

If you have the user id, however, you'll need to loop through all of the Session objects, deserializing each one and looking for one which has a key named "_auth_user_id", and for which the value of that key is the user id.

James Bennett
+6  A: 

Modifying the django_session table to add an explicit user_id can make life a lot easier. Assuming you do that (or something similar), here are four approaches to munging things to your liking:

Fork the djago.contrib.session code. I know, I know, that's a horrible thing to suggest. But it's only 500 lines including all backends and minus the tests. It's pretty straightforward to hack. This is the best route only if you are going to do some serious rearranging of things.

If you don't want to fork, you could try connecting to the Session.post_save signal and munge there.

Or you could MonkeyPatch contrib.session.models.Session.save(). Just wrap the existing method (or create a new one), breakout/synthesize whatever values you need, store them in your new fields, and then super(Session, self).save().

Yet another way of doing this is to put in 2 (yes, two) middleware classes -- one before and one after SessionMiddleware in your settings.py file. This is because of the way middleware is processed. The one listed after SessionMiddleware will get, on the inbound request, a request with the session already attached to it. The one listed before can do any processing on the response and/or change/resave the session.

We used a variation on this last technique to create pseudo-sessions for search engine spiders to give them special access to material that is normally member-only. We also detect inbound links where the REFERER field is from the associated search engine and we give the user full access to that one article.

Peter Rowell