Amir Salihefendic
amix at amix.dk
Fri Aug 13 14:30:23 EDT 2004
Thanks a lot for your time spent on the reply, I appreciate it. "Under what circumstances do you call createSession() instead of getSameSession()?" Let's take another example: I am making a blog-system where I need to have an admin section. I am using the publisher handler. Simple forms post username and password to admin.py Admin.py has an index function, which has username and password as input. In the index function I check if the username and password match, if they do I create an session and store username and password. Now, I need to redirect to a new function viewPosts (it's also located in the admin module). In viewPosts I have to check if the right session is set - else somebody could do admin.py/viewPosts and get access to the admin section. Of course, I could solve problem in many other ways: - Send the SID to viewPosts - Place everything in one function (i.e. place everything in admin.py/index) - "Append" the session to the req object - Make viewPosts private (i.e. do _viewPosts) and then I can only access it by going through admin.py/index -etc. Anyway, I am interested in knowing: What is the smartest way to "share"/access same session across functions (i.e. when you are internal "redirecting")? Example of what I mean by "redirecting" (not working...): def createSession(req): new_session = Session.Session(req) return getSameSession(req) def getSameSession(req): same_session = Session.Session(req) return same_session.id() My guess is to send the SID (working). This seems to be a very light and easy approach: def createSession(req): new_session = Session.Session(req) new_session.unlock() #Check id req.write(new_session.id()) return getSameSession(req, new_session.id()) def getSameSession(req, SID): same_session = Session.Session(req, SID) #Check id req.write("\n%s\n" % same_session.id()) return "Done" (This is a solution I use now.) Of course this is very simplified example... Med venlig hilsen / Kind regards Amir Salihefendic ----- What we do in life echoes in eternity Den 13/8-2004, kl. 1.17, skrev Byron Ellacott: > Amir Salihefendic wrote: >> I welcome myself to this list ;-) > > Welcome! > > [working example] >> def createSession(req): >> def getSameSession(req): > > The important thing to note here is that the code is identical in both > calls. That is, if you call Session.Session(req) with no session ID > in cookies, or the existing session ID has no matching session stored > on disk, a new session ID is generated. > > But, the session is /not/ written to disk. > >> def createSession(req): >> return getSameSession(req) >> def getSameSession(req): >> return same_session.id() > > So when you change to calling getSameSession() from createSession() > you are in fact creating /two/ sessions. My guess would be that your > apparent infinite loop is in fact a deadlock, caused by the fact that > your second created session will be reusing the session ID created by > the first one, and then attempting to establish a global lock on that > session ID. Bad. > >> This does not work - it makes an infinitive loop..! Now to fix this >> you need to unlock the session in createSession (.. I have no clue >> why you have to do this..?). And then you need to restart apache... >> i.e.: > > This bears up my analysis well. The locking done by the Session > module is an Apache-wide lock on the session ID. So, when > createSession() first creates a session, it locks that sid. Then, it > calls getSameSession() which attempts to lock the same sid. The lock > call blocks here, waiting for the first lock to be released, but that > release will never come. If you cause the first created session to > unlock itself, you will not create a deadlock, but you will need to > restart apache to break an existing deadlock. > >> But this does not work quite well.. If you delete the Session: >> And then you do this: >> First time the id's aren't same - after that they are the same. > > When a session has been deleted, it is marked as invalid and calling > .load() on that sid will fail. .__init__() will create a new sid if > .load() fails for an existing one, so I suspect you are seeing this > behaviour. > > Overall, it seems you are making the session management process far > more complicated than it needs to be. Under what circumstances do you > call createSession() instead of getSameSession() ? > > I am successfully using the Session module to handle an HTML forms > based login system: > > session = Session.Session(req) > if NeedAuth and not session.has_key('username'): > redirect(AuthPage) > ServePage(req) > session.save() > return apache.OK > > This is a simplification, since I use an extensible application object > that allows you to change how sessions are generated and how users are > authenticated, but it boils down to the above. I create a new session > or get an existing session. I do not care which. If the page being > requested needs auth, but the session doesn't contain a username key, > I redirect[1] to the login page, which stores the username value into > the session if the user presents the right credentials. Otherwise, I > serve the requested page, then save the session, and Bob's a builder. > > Note that I cannot distinguish between an expired session and no > session at all, but this is a limitation of the Session module. I can > distinguish between a new session and an existing session by calling > session.is_new(), but that distinction turns out not to be very > important. > > At some point, I will need to extract the sid from the cookie set > myself, to be able to distinguish between a timed out session, an > invalidated session, a missing session and a brand new session. (Or > else I'll have to patch the Session module, which I'm not real keen to > do.) > > -- > bje > > [1] The 'redirects' I do are simply changing what view my code > believes it is processing, so execution continues down the line, and > session.save() is called in due order. If you're using an Apache > internal redirect or a 302/303 redirect, you should ensure new > sessions are saved as soon as created with "if session.is_new(): > session.save()". > _______________________________________________ > Mod_python mailing list > Mod_python at modpython.org > http://mailman.modpython.org/mailman/listinfo/mod_python >
|