我为我的烧瓶登录使用了一个烧瓶片段来检查用户是否已登录:
from functools import wraps
def logged_in(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if session.get('logged_in') is not None:
return f(*args, **kwargs)
else:
flash('Please log in first.', 'error')
return redirect(url_for('login'))
return decorated_function
我像这样装饰视图:
@app.route('/secrets', methods=['GET', 'POST'])
@logged_in
def secrets():
error = None
我也想为授权做类似的事情。现在,我有很多视图来检查用户是否拥有资源,比如说hotdogs
资源。
如果登录用户是该特定热狗的所有者,他可以编辑和管理他的热狗。如果他不是,我会把他踢到未经授权的屏幕上。
@app.route('/<hotdog>/addmustard/',methods=["GET"])
@logged_in
def addmustard(hotdog):
if not (authorizeowner(hotdog)):
return redirect(url_for('unauthorized'))
do_stuff()
authorizeowner()
将热狗作为输入并检查记录的热狗所有者是否与会话变量中列出的所有者名称匹配。
我尝试制作一个类似于我登录的 owns_hotdog 包装器/装饰器功能,但它抱怨它不接受参数。我怎样才能实现类似的目标?就像是...
def owns_hotdog(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not authorizeowner(hotdog):
return f(*args, **kwargs)
else:
flash('Please log in first.', 'error')
return redirect(url_for('login'))
return decorated_function
从错误消息来看,装饰器似乎没有收到 Flask 视图可以从路由中的变量访问的 hotdog 参数。我的希望是……
@app.route('/<hotdog>/addmustard/',methods=["GET"])
@logged_in
@owns_hotdog(hotdog)
def addmustard(hotdog):
do_stuff()
一切都适用于我当前的 authorizeowner(hotdog) 函数,但是将它作为我的路由顶部的包装器而不是作为路由内的第一行似乎更干净。
其他一些注意事项:
- 我知道 Flask-Security 和 Flask-Principal 可以为我管理授权。不幸的是,我使用的是不受支持的数据库后端,无法使用这些扩展。所以,我被迫在没有他们的情况下进行身份验证。
- 如果您在以这种方式进行授权时发现任何明显的漏洞,请告诉我!