From: Stuart D. <st...@as...> - 2003-02-18 05:30:04
|
Geoffrey Talvola wrote: >Stuart Donaldson [mailto:st...@as...] 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() |