我使用cherrypy作为Web服务器,我想在返回页面之前检查用户的登录状态。这适用于主Application类(在site.py
中)中的方法,但是当我在网页树中较深的一层(在单独的文件中)中调用方法上的相同修饰函数时会出错。
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'值,并将其与我们的数据库进行比较,如果ID匹配则传递它。
抱歉,我不知道Analyze()和Api()以及User()页面是子类,嵌套类,扩展方法还是什么。所以我无法给出一个精确的标题。我是否需要以某种方式将父类传递给它们?
这里的问题是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以便稍后在调用处理程序时在处理程序上安装该工具。
如果该类上的所有方法都需要该工具,则可以在类本身上使用该config装饰器。
您也可以在服务器配置中为给定端点启用该工具,如另一个问题中所述。