Geoffrey Talvola wrote:
>Stuart Donaldson [mailto:stu@...] wrote:
>
>
>>That is rather interesting. The SecureCountVisits page does
>>not check
>>for Application.createSessionForTransaction() as does the CountVisits
>>
>>
>page.
>
>
>>It appears that when a session expires, the strategy is to call
>>Application.handleInvalidSession() which basically removes the _SID_
>>reference so the browser will stop requesting an invalid session, and
>>marks request._sessionExpired. It does not however, delete
>>the session
>>object.
>>
>>
>
>Yes it does -- see Application.isSessionIdProblematic() which explicitly
>calls "del self._sessions[sid]" on an expired session.
>
>
Ok, so perhaps my statement could have been more explicit. While it does
delete the session object from the store, the reference is not removed
from the transaction. The transaction continues to to reference the
existing expired session.
>>The sesion object remains attatched to the transaction for
>>the remainder
>>of the transaction processing by the servlet. It is up to
>>the servlet
>>to check the request.isSessionExpired() and take appropriate
>>action of
>>notifying the user that their session has expired at this point.
>>
>>
>
>I don't think that's quite what's happening. I think this is what happens
>on an expired session:
>
>1. The Transaction object is constructed, and transaction._session is
>initialized to None.
>2. Application.isSessionIdProblematic() detects the expired session and
>deletes it from self._sessions.
>3. Application.handleInvalidSession() is called, which clears the _SID_
>cookie and/or field (if the IgnoreInvalidSession setting is enabled,
>otherwise it returns an error message).
>4. Sometime later in the request processing, self.session() is called...
>5. ...which calls Application.createSessionForTransaction()...
>6. ...which calls Request.sessionId() to get the session ID...
>7. ...which returns None because the session ID was cleared in step 3 above
>8. Therefore Application.createSessionForTransaction() creates a _new_
>session.
>
This is correct up to point 5. The session already exists on the
transaction so createSessionForTransaction() is not called there. Note:
it was called as a result of step 2 at isSessionIdProblematic() where
request.session() results in a call to createSessionForTransaction().
>So as far as I can tell, the call to self.session() is handled as though
>there was no session at all, and a new empty session is created.
>
>
That is what happens on the first transaction after the transaction
where the expired session was detected.
>There's no need to call isSessionExpired() unless you specifically want to
>treat an expired session differently from a non-existant session. It
>depends on what your application is doing. The SecurePage example handles
>both cases the same way, and simply sends the user back to the login page,
>but it could certainly be done differently.
>
>Am I missing something here? I don't see any problem.
>
>
Yes, I think it is not obvious that deleting the session object from the
session store does not remove it from the transaction object. The
reference to the session object in SecurePage.awake() continue to
reference the expired session on the first transaction after it expired.
This can be confirmed by enabling session debugging, and printing out
the session ID in the awake method. It is clear that the session has
been deleted in handleInvalidSession() and the same session ID is on the
session in the awake method.
The following patch to SecurePage.py will resolve the problem in
SecurePage, and gives the desired output indicating that the session has
expired.
Note: I've put this into CVS as well.
===================================================================
RCS file: /cvsroot/webware/Webware/WebKit/Examples/SecurePage.py,v
retrieving revision 1.8
diff -u -r1.8 SecurePage.py
--- Examples/SecurePage.py 20 Jun 2002 17:48:17 -0000 1.8
+++ Examples/SecurePage.py 18 Feb 2003 05:21:37 -0000
@@ -49,6 +49,12 @@
request.setField('extra', 'You have been
logged out.')
request.setField('action',
string.split(request.urlPath(), '/')[-1])
app.forward(trans, 'LoginPage')
+ elif request.isSessionExpired():
+ # Login page with a "logged out" message.
+ session.values().clear()
+ request.setField('extra', 'Your session
has expired.')
+ request.setField('action',
string.split(request.urlPath(), '/')[-1])
+ app.forward(trans, 'LoginPage')
elif request.hasField('login') and
request.hasField('username') and request.hasField('password'):
# They are logging in. Clear session
session.values().clear()
|