RES: [mod_python] The right way to handle sessions

AJDENSTONE at BKB.com.br AJDENSTONE at BKB.com.br
Mon Aug 23 13:30:27 EDT 2004


Hi Amir.

	You can add your code snippet in the mod_python wiki cookbook
(http://modpython.coedit.net/CookBook). 

	Regards,

Alexandre Denstone
BankBoston - Retail Internet Systems
* ajdenstone at bkb.com.br


-----Mensagem original-----
De: Amir Salihefendic [mailto:amix at amix.dk] 
Enviada em: sexta-feira, 13 de agosto de 2004 12:32
Para: mod_python user mailing list
Assunto: Re: [mod_python] The right way to handle sessions


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

Argh forgot something very important (to save the damn session)!: def
createSession(req):
     new_session = Session.Session(req)
     new_session.save()
     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)
     same_session.load()

     #Check id
     req.write("\n%s\n" % same_session.id())

     return "Done"

*Tsk tsk*

Med venlig hilsen / Kind regards
Amir Salihefendic
-----
What we do in life echoes in eternity
Den 13/8-2004, kl. 13.30, skrev Amir Salihefendic:

> 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
>>
>
> _______________________________________________
> Mod_python mailing list
> Mod_python at modpython.org 
> http://mailman.modpython.org/mailman/listinfo/mod_python
>

_______________________________________________
Mod_python mailing list
Mod_python at modpython.org
http://mailman.modpython.org/mailman/listinfo/mod_python


Esta mensagem, incluindo seus anexos, pode conter informacao confidencial
e/ou privilegiada. Se voce recebeu este e-mail por engano, nao utilize,
copie ou divulgue as informacoes nele contidas. E, por favor, avise
imediatamente o remetente, respondendo ao e-mail, e em seguida apague-o.
Este e-mail possui conteudo informativo e nao transacional. Caso necessite
de atendimento imediato, recomendamos utilizar um dos canais disponiveis:
Internet Banking <http://www.bankboston.com.br>  , BankBoston por telefone
<http://www.bankboston.com.br/bpt>  ou agencia/representante de atendimento
de sua conveniencia. Agradecemos sua colaboracao.
This message, including its attachments, may contain confidential and/or
privileged information. If you received this email by mistake, do not use,
copy or disseminate any information herein contained. Please notify us
immediately by replying to the sender and then delete it. This email is for
information purposes only, not for transactions. In case you need immediate
assistance, please use one of the following channels: Internet Banking
<http://www.bankboston.com.br>  ,  BankBoston by phone
<http://www.bankboston.com.br/bpt>  or branch/relationship manager at your
convenience. Thank you for your cooperation.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://modpython.org/pipermail/mod_python/attachments/20040823/46671728/attachment-0001.html


More information about the Mod_python mailing list