通过角色限制访问烧瓶视图某些区域的功能?


问题内容

我写了这个,看起来似乎很好:

@app.route('/admin', methods=['GET','POST'])
@login_required
def admin():
    if not current_user.role == ROLE_ADMIN:
        flash('You do not have access to view this page.')
        return redirect(url_for('index'))
...the rest of my code...

由于不想将这3行添加到我只希望管理员可见的每个区域,因此在尝试简化操作时,我尝试将其放入类似这样的函数中:

def admin_only():
    if not current_user.role == ROLE_ADMIN:
        flash('You do not have access to view this page.')
        return redirect(url_for('index'))

然后放入我的视图功能:

@app.route('/admin', methods=['GET','POST'])
@login_required
def admin():
    admin_only()
...the rest of my code....

但是,这不符合我的预期。我收到了闪烁的消息,但是它没有像我想象的那样重定向。

因此,有两个问题:

  1. 为什么返回的重定向不起作用?
  2. 有没有更好的方法来实现此功能?

问题答案:

真正回答您的问题。您应该使admin_only函数成为装饰器并装饰adminview方法。现在不重定向的原因是因为您没有从视图返回重定向。

def admin():
    ret = admin_only()
    if( not ret ):
        return ret
....

那应该可以解决您当前的问题,但这不是理想的选择,您希望将其功能转移到装饰器上。

我还建议以下内容:

看一下Flask-Principal,它提供了向用户分配角色,然后基于这些角色将访问限制到视图的功能。

与Flask-Principal一起查看Flask-Security,因为它提供了许多有用的与安全相关的Flask扩展,并且使其更易于使用。

使用示例:

@roles_required( "admin" )
def website_control_panel():
    return "Only Admin's can see this."


允许将具有角色角色的用户admin附加到其帐户。另一个用例是允许用户具有可以用指定的多种角色之一,roles_accepted并且可以按以下方式使用:

@roles_accepted( "journalist", "editor" )
def edit_paper():
    return render_template( "paper_editor.html", ... )

将只允许具有journalist或至少一个editor角色与其帐户绑定的用户。