这篇文章将为大家详细讲解有关如何解决python中Flask装饰器顺序问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
成都创新互联公司自2013年创立以来,先为源汇等服务建站,源汇等地企业,进行企业商务咨询服务。为源汇企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。前言
这个题是用 flask 框架写的,在 www/bookhub/views/user.py
中, refresh_session
方法存在未授权访问漏洞,代码是这样写的:
@login_required @user_blueprint.route('/admin/system/refresh_session/', methods=['POST']) def refresh_session(): pass # 这里省略内容
注意看 @login_required
这个装饰器写在了 route
装饰器上面了,导致了 login_required
未调用。那么,为什么会这样子呢?
官方文档
Flask 官方文档中关于Login Required Decorator说明 这一节里面有一行说明:
To use the decorator, apply it as innermost decorator to a view function. When applying further decorators, always remember that the route() decorator is the outermost.
大概意思就是,必须保证 route 装饰器在最顶层
那么为什么要这样提示呢?
Python 装饰器顺序说明
本节内容可直接参考: Python 装饰器执行顺序迷思
总结一下就是,装饰的顺序按靠近函数顺序执行,从内到外装饰,调用时由外而内,执行顺序和装饰顺序相反。
回过头来看 Flask
Flask 框架中, route
装饰器是这么写的:
def route(self, rule, **options): """Like :meth:`Flask.route` but for a blueprint. The endpoint for the :func:`url_for` function is prefixed with the name of the blueprint. """ def decorator(f): endpoint = options.pop("endpoint", f.__name__) self.add_url_rule(rule, endpoint, f, **options) return f return decorator
route
调用了 add_url_rule
, 对传入的 f
添加一条 URL 规则。
所以,按照 python 装饰器顺序:
如果 @app.route
在内层,那么就会把最原始的 view 函数传给 add_url_rule , Flask 框架就会添加一条 URL 规则,指向最原始的 view 函数。
如果 @app.route
在外层,那么就会把已经被 login_required 装饰过的 view 函数传给 add_url_rule , Flask 框架就会添加一条 URL 规则,指向已经装饰过的 view 函数。
下面是两个例子,来说明:
正确写法
@user_blueprint.route('/admin/refresh_session/', methods=['POST']) @login_required def refresh_session(): pass
这段代码相当于:
# 这里没有装饰器 def refresh_session(): pass login_wrapped = login_required(refresh_session) # login 装饰器 both_wrapped = app.route('/admin/refresh_session/')(login_wrapped) # route 装饰器
/admin/refresh_session/
这条路由指向的实际是 login_wrapped
,这样就会经过 login 检查
错误写法
@login_required @user_blueprint.route('/admin/refresh_session/', methods=['POST']) def refresh_session(): pass
这段代码相当于:
# 这里没有装饰器 def refresh_session(): pass route_wrapped = app.route('/admin/refresh_session/')(refresh_session) # route 装饰器 login_wrapped = login_required(route_wrapped) # login 装饰器
/admin/refresh_session/
这条路由指向的实际是 refresh_session
, 而 login_wrapped
并没有与路由挂勾,所以不会被调用。
关于“如何解决python中Flask装饰器顺序问题”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
售后响应及时
7×24小时客服热线数据备份
更安全、更高效、更稳定价格公道精准
项目经理精准报价不弄虚作假合作无风险
重合同讲信誉,无效全额退款