1. cherrypy
  2. CherryPy
Issue #224 resolved

[PATCH] possible improvement to sessionauthenticatefilter.py

Anonymous created an issue

Hello,

Currently, sessionAuthenticateFilter will call the loadUserByUsername function (if it is defined) on every request. My understanding is that this function should be used to fetch user details and store it in an easily accessible place, which at the moment is cherrypy.threadData.user

The problem arises when you want to fetch user details from a database; a database fetch on every request may slow things down.

I've modified the code to store the user details in the session, rather than cherrypy.threadData.user, and only once when the user logs in. Here is the patch, let me know what you think:

{{{ Index: sessionauthenticatefilter.py =================================================================== --- sessionauthenticatefilter.py (revision 461) +++ sessionauthenticatefilter.py (working copy) @@ -81,7 +81,12 @@ if errorMsg: cherrypy.response.body = loginScreen(fromPage, login = login, errorMsg = errorMsg) else: - sessionMap[sessionKey] = login + + if loadUserByUsername: + sessionMap[sessionKey] = loadUserByUsername(login) + else: + sessionMap[sessionKey] = login + if not fromPage: fromPage = '/' cherrypy.response.body = httptools.redirect(fromPage) @@ -95,8 +100,3 @@ if not sessionMap.get(sessionKey): cherrypy.response.body = loginScreen(cherrypy.request.browserUrl) return - - # Everything is OK: user is logged in - if loadUserByUsername: - username = sessionMap[sessionKey] - cherrypy.threadData.user = loadUserByUsername(username) }}}

Reported by sean.dawson@gmail.com

Comments (8)

  1. Anonymous

    I agree that this could be a useful feature but it should be configurable ... We won't include this in 2.2 though so I'm moving it to post-2.2

  2. Robert Brewer

    Fixed in [1324] for CP 3. The builtin session auth now has no equivalent to loadUserByUsername; in its place is an 'on_check' hook which runs once for each request. So if you used to provide loadUserByUsername, you can do the same thing now via:

    def load_user():
        if not getattr(cherrypy.request, 'user'):
            cherrypy.request.user = my_load_func(cherrypy.session['username'])
    
    conf['tools.session_auth.on_check'] = load_user
    

    The fix for this ticket is to write an on_login handler (which runs once when the user logs in) instead:

    def load_user():
        sess = cherrypy.session
        if not sess.get('user_data'):
            sess['user_data'] = my_load_func(sess['username'])
    
    conf['tools.session_auth.on_login'] = load_user
    
  3. Log in to comment