bottle hooks with beaker session middleware and checking logins
Question
I'm writing a bottle application with beaker session middleware.
My code is has this:
@bottle.route('/')
def slash():
try:
beaker_session = request.environ['beaker.session']
except:
#redirect('/login')
abort(401, "Failed beaker_session in slash")
try:
name = beaker_session['name']
except:
redirect('/login')
for each route request except /login. I know there is a bottle hook system to do things before requests, but I'm not sure how best to use it to check if someone is logged in or not.
I'm fairly new to python webapps using bottle. Not to many people are using it with beaker session middleware so I don't have a lot of examples to go by.
Thanks for any help or pointers!
PS. The entire code for this is in this repo: https://github.com/curtisgithub/labinski/blob/master/labinski.py
Solution
I know there is a bottle hook system to do things before requests, but I'm not sure how best to use it to check if someone is logged in or not.
You can use the before_request
hook to run code prior to each request, but checking authentication here only makes sense if you expect all access to be authenticated. You could do something like this:
@bottle.hook('before_request')
def setup_request():
try:
beaker_session = request.environ['beaker.session']
except:
#redirect('/login')
abort(401, "Failed beaker_session in slash")
try:
name = beaker_session['name']
except:
redirect('/login')
...but without some extra code this is going to result in a redirect loop when someone actually requests /login
. So you can add this to the hook, maybe:
if request.urlparts.path == '/login':
continue
Another solution is to implement similar functionality using a Python decorator, which lets you control access on a method-by-method basis. For example, you could say something like:
@route('/')
@authenticated
def index():
return 'This is /.'
@route('/login')
def login():
return 'This is login.'
And then your authenticated
decorator would look very much like the hook:
def authenticated(func):
def wrapped(*args, **kwargs):
try:
beaker_session = request.environ['beaker.session']
except:
abort(401, "Failed beaker_session in slash")
try:
name = beaker_session['name']
return func(*args, **kwargs)
except:
redirect('/login')
return wrapped