Search code examples
pythonwebcherrypy

Checking login status at every page load in CherryPy


I am in the midst of writing a web app in CherryPy. I have set it up so that it uses OpenID auth, and can successfully get user's ID/email address.

I would like to have it set so that whenever a page loads, it checks to see if the user is logged in, and if so displays some information about their login.

As I see it, the basic workflow should be like this:

  1. Is there a userid stored in the current session? If so, we're golden.
  2. If not, does the user have cookies with a userid and login token? If so, process them, invalidate the current token and assign a new one, and add the user information to the session. Once again, we're good.
  3. If neither condition holds, display a "Login" link directing to my OpenID form.

Obviously, I could just include code (or a decorator) in every public page that would handle this. But that seems very... irritating.

I could also set up a default index method in each class, which would do this and then use a (page-by-page) helper method to display the rest of the content. But this seems like a nightmare when it comes to the occasional exposed method other than index.

So, my hope is this: is there a way in CherryPy to set some code to be run whenever a request is received? If so, I could use this to have it set up so that the current session always includes all the information I need.

Alternatively, is it safe to create a wrapper around the cherrypy.expose decorator, so that every exposed page also runs this code?

Or, failing either of those: I'm also open to suggestions of a different workflow. I haven't written this kind of system before, and am always open to advice.


Edit: I have included an answer below on how to accomplish what I want. However, if anybody has any workflow change suggestions, I would love the advice! Thanks all.


Solution

  • Nevermind, folks. Turns out that this isn't so bad to do; it is simply a matter of doing the following:

    1. Write a function that does what I want.
    2. Make the function in to a custom CherryPy Tool, set to the before_handler hook.
    3. Enable that tool globally in my config.