我使用cherrypy作为Web服务器,我想在返回页面之前检查用户的登录状态。这适用于主Application类中的方法(在site.py
中),但是当我在网页树中较深的一层(在单独的文件中)中调用方法上的相同修饰函数时会出错。 / p>
validate_user()
是用作装饰器的函数。它要么将用户传递给页面,要么将其作为cherrypy.Tool
发送到401受限页面,如下所示:
from user import validate_user
cherrypy.tools.validate_user = cherrypy.Tool('before_handler', validate_user)
我将网站的不同部分附加到主site.py
文件的Application类,方法是将子类的实例分配为变量:
from user import UserAuthentication
class Root:
user = UserAuthentication() # maps user/login, user/register, user/logout, etc
admin = Admin()
api = Api()
@cherrypy.expose
@cherrypy.tools.validate_user()
def how_to(self, **kw):
from other_stuff import how_to_page
return how_to_page(kw)
但是,当我尝试在Admin或Api或Analysis部分中使用validate_user()
时,这不起作用。这些是在单独的文件中。
import cherrypy
class Analyze:
@cherrypy.expose
@cherrypy.tools.validate_user() #### THIS LINE GIVES ERROR ####
def explore(self, *args, **kw): # @addkw(fetch=['uid'])
import explore
kw['uid'] = cherrypy.session.get('uid',-1)
return explore.explorer(args, kw)
错误是cherrypy.tools没有validate_user函数或方法。但是我在site.py中分配的其他内容确实出现在这里。我在单独的文件中使用此工具的原因是什么?该文件是我整个网站地图的一部分?
如果这是相关的,那么validate_user()函数只需查看cherrypy.request.cookie,找到' session_token' value,并将其与我们的数据库进行比较,并在ID匹配时传递它。
抱歉,我不知道Analyze()和Api()以及User()页面是子类,嵌套类,扩展方法还是什么。所以我无法给出一个精确的标题。我是否需要以某种方式将父类传递给它们?
答案 0 :(得分:1)
这里的问题是Python在导入期间处理除函数/方法体之外的所有内容。所以在site.py
中,import user
(或from user import <anything>
),导致所有user
模块在之前被处理 Python解释器具有得到了validate_user
工具的定义,包括装饰器,它试图按值访问该工具(而不是通过引用)。
CherryPy还有另一种使用config来装饰函数的机制,可以在这些处理程序上启用工具。而不是@cherrypy.tools.validate_user
,请使用:
@cherrypy.config(**{"tools.validate_user.on": True})
这个装饰器可以工作,因为它不需要从validate_user
访问cherrypy.tools
来将自己安装在处理程序上,而是在调用处理程序时,配置CherryPy以便稍后在处理程序上安装该工具。 / p>
如果该类上的所有方法都需要该工具,则可以在类本身上使用该配置装饰器。
您也可以在服务器配置中为给定端点启用该工具,如另一个问题中所述。