|
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
>
|