Написание CherryPy Decorator для авторизации
У меня есть приложение cherrypy, и на некоторых из представлений я хочу начать, позволяя только определенным пользователям просматривать их и отправляя кого-либо еще на страницу, требующую авторизации.
Есть ли способ сделать это с помощью специального декоратора? Я думаю, что это будет самый элегантный вариант.
Вот основной пример того, что я хочу сделать:
class MyApp:
@authorization_required
def view_page1(self,appID):
... do some stuff ...
return html
def authorization_required(func):
#what do I put here?
Также может ли функция authorization_required при вызове в качестве декоратора принимать такие параметры, как allow_group1, allow_group2? Или мне нужен отдельный декоратор для каждой группы?
2 ответа
Хорошо, в этом случае ваш декоратор будет выглядеть примерно так:
# without any parameters
def authentication_required(f):
@functools.wraps(f)
def _authentication_required(*args, **kwargs):
# Do you login stuff here
return f(*args, **kwargs)
return _authentication_required
# With parameters
def authentication_required(*allowed_groups):
def _authentication_required(f):
@functools.wraps(f)
def __authentication_required(*args, **kwargs):
# Do you login stuff here
return f(*args, **kwargs)
return __authentication_required
return _authentication_required
Вы действительно не хотите писать собственные декораторы для CherryPy. Вместо этого вы хотите написать новый инструмент:
def myauth(allowed_groups=None, debug=False):
# Do your auth here...
authlib.auth(...)
cherrypy.tools.myauth = cherrypy.Tool("on_start_resource", myauth)
См. http://docs.cherrypy.org/en/latest/extend.html для дальнейшего обсуждения. Это имеет несколько преимуществ по сравнению с написанием собственного декоратора:
- Вы получаете декоратор бесплатно из инструмента:
@cherrypy.tools.myauth(allowed_groups=['me'])
и он уже знает, как не затереть cherrypy.exposed на ту же функцию. - Вы можете применять инструменты для каждого обработчика (с декоратором), для каждого дерева контроллера (через
_cp_config
) или per-URI-дерево (в конфигурационных файлах или файлах). Вы даже можете смешивать их и предоставлять базовую функцию через декораторы, а затем переопределять их поведение в файлах конфигурации. - Если файл конфигурации отключает вашу функцию, вы не платите за производительность, вызывая функцию декоратора, просто чтобы проверить, отключена ли она.
- Вы не забудете добавить аргумент 'debug', как во всех встроенных инструментах.;)
- Ваша функция может быть запущена раньше (или позже, если это то, что вам нужно), чем пользовательский декоратор, выбрав другую "точку".
- Ваша функция может работать в нескольких точках подключения, если это необходимо.