Flask-RBAC在Flask应用程序中提供基于角色的访问控制模块。它可以帮助您控制用户访问您网站的不同角色。
配置您的应用程序
与许多Flask扩展一样,您需要配置您的应用程序:
from flask import Flask
from flask_rbac import RBAC
app = Flask(__name__)
rbac = RBAC(app)
或者您可以使用工厂方法进行配置:
from flask import Flask
from flask_rbac import RBAC
rbac = RBAC()
def create_app():
app = Flask(__name__)
rbac.init_app(app)
return app
模式设定
Flask-RBAC有两种模式,<cite>RBAC_USE_WHITE</cite>决定是否使用白名单来检查权限。它将<cite>False</cite>设置为默认值。
RBAC_USE_WHITE = True | 只允许规则可以访问资源。这意味着,您未添加的所有拒绝规则和规则都无法访问资源。 |
RBAC_USE_WHITE = False | 只有拒绝规则才能访问资源。 |
改变它:
app.config['RBAC_USE_WHITE'] = True
设置角色模型
Flask-RBAC在RoleMixin类中实现了Flask-RBAC所需的一些方法。您可以使用RoleMixin作为您的角色模型:
class Role(RoleMixin):
pass
anonymous = Role('anonymous')
但是,如果您的应用程序在SQLAlchemy下工作,并且您希望将角色保存在数据库中,则需要覆盖Role类以调整您的应用程序,这是一个示例:
from flask_rbac import RoleMixin
from your_package.app import db
roles_parents = db.Table(
'roles_parents',
db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
db.Column('parent_id', db.Integer, db.ForeignKey('role.id'))
)
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
parents = db.relationship(
'Role',
secondary=roles_parents,
primaryjoin=(id == roles_parents.c.role_id),
secondaryjoin=(id == roles_parents.c.parent_id),
backref=db.backref('children', lazy='dynamic')
)
def __init__(self, name):
RoleMixin.__init__(self)
self.name = name
def add_parent(self, parent):
# 你并不需要添加这个角色设定父母的孩子,
# 角色之间的关系#会做这项工作自动
self.parents.append(parent)
def add_parents(self, *parents):
for parent in parents:
self.add_parent(parent)
@staticmethod
def get_by_name(name):
return Role.query.filter_by(name=name).first()
创建角色模型后,您可以将模型添加到Flask-RBAC:
rbac.set_role_model(Role)
或者使用装饰器为Flask-RBAC设置角色模型:
@rbac.as_role_model
class Role(RoleMixin):
# codes go here
设置用户模型
与RoleMixin相同,UserMixin为Flask-RBAC实现了一些方法,您可以直接扩展它:
from flask_rbac import UserMixin
class User(UserMixin):
pass
a_user = User()
好吧,如果您的应用程序在SQLAlchemy下工作:
from flask_rbac import UserMixin
from your_package.app import db
users_roles = db.Table(
'users_roles',
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
db.Column('role_id', db.Integer, db.ForeignKey('role.id'))
)
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), unllable=True)
# Other columns
roles = db.relationship(
'Role',
secondary=users_roles,
backref=db.backref('roles', lazy='dynamic')
)
def add_role(self, role):
self.roles.append(role)
def add_roles(self, roles):
for role in roles:
self.add_role(role)
def get_roles(self):
for role in self.roles:
yield role
与角色模型相同,您应该将用户模型添加到Flask-RBAC:
rbac.set_user_model(User)
或者使用装饰器:
@rbac.as_user_model
class User(UserMixin):
# codes go here
设置用户加载器
Flask-RBAC需要知道谁是当前用户,因此它要求您提供一个函数,告诉它谁是当前用户。
如果您默认安装Flask-RBAC将从Flask-Login加载当前用户。
如果您将当前用户保存在 <cite>flask.g中</cite>,以下是您的示例:
from flask import g, current_app
@app.route('/signin', methods=['POST'])
@rbac.allow(['anonmous'], methods=['POST'])
def signin():
# Sign in logic...
g.current_user = user
def get_current_user():
with current_app.request_context():
return g.current_user
rbac.set_user_loader(get_current_user)
设置访问规则
您可以使用<cite>allow</cite>和<cite>deny</cite>向Flask-RBAC添加规则:
@app.route('/')
@rbac.allow(['anonymous'], methods=['GET'])
def index():
# your codes.
pass
@app.route('/account/signin', methods=['GET', 'POST'])
@rbac.deny(['logged_user'], methods=['GET', 'POST'])
def signin():
# show sign in page or handle sign in request.
pass
上面的代码添加了两个规则:
允许匿名角色的用户使用GET /。
将login_user角色的用户拒绝到GET和POST / account / signin。
API参考
Flask.ext.rbac.RBAC
class flask_rbac.init.RBAC(app=None, **kwargs)
此类在Flask中实现基于角色的访问控制模块。初始化Flask-RBAC有两种方法:
app = Flask(__name__)
rbac = RBAC(app)
或者
rbac = RBAC
def create_app():
app = Flask(__name__)
rbac.init_app(app)
return app
参数:
app - Flask对象
参数
- role_model - 自定义角色模型
- user_model - 自定义用户模型
- user_loader - 自定义用户加载程序,用于加载当前用户
- permission_failed_hook - 在权限被拒绝时调用。
allow(roles, methods, with_children=True)
这是一个装饰功能。
您可以允许角色使用它访问视图功能。
一个例子
@app.route('/website/setting', methods=['GET', 'POST'])
@rbac.allow(['administrator', 'super_user'], ['GET', 'POST'])
def website_setting():
return Response('Setting page.')
参数:
- roles - 列出,角色的每个名称。请注意, 匿名是指匿名。如果您向规则添加匿名,则每个人都可以访问该资源,除非您拒绝其他角色。
- methods - List,方法的每个名称。方法在['GET','POST','PUT','DELETE']中有效
- with_children - 是否允许角色的孩子。默认为True。
as_role_model(model_cls)
用于设置自定义模型或角色的装饰器。
- model_cls - 角色模型。
as_user_model(model_cls )
用于设置自定义模型或用户的装饰器。
- model_cls - 角色模型。
deny(roles, methods, with_children=False)
这是一个装饰功能。
您可以拒绝角色来使用它访问视图功能。
一个例子:
@app.route('/article/post', methods=['GET', 'POST'])
@rbac.deny(['anonymous', 'unactivated_role'], ['GET', 'POST'])
def article_post():
return Response('post page.')
参数
- roles 列出,角色的每个名称。
- methods List,方法的每个名称。方法在
- with_children 是否允许角色的孩子。默认为True
exempt(view_func)
免除视图功能被检查权限。使用白名单检查时非常有用。
例
@app.route('/everyone/can/access')
@rbac.exempt
def everyone_can_access():
return 'Hello~'
参数
view_func - 视图函数将被免除。
get_app(reference_app=None)
Helper方法,用于实现查找应用程序的逻辑。
has_permission(method, endpoint, user=None)
返回当前用户是否可以访问该资源。例:
@app.route('/some_url', methods=['GET', 'POST'])
@rbac.allow(['anonymous'], ['GET'])
def a_view_func():
return Response('Blah Blah...')
如果你没有登录。
rbac.has_permission(‘GET’, ‘a_view_func’) return True.
rbac.has_permission(‘POST’, ‘a_view_func’) return False.
参数
method – 方法等待检查
endpoint – 应用程序端点。
user – 您需要检查的用户。默认为当前用户
init_app(app)
在Flask-RBAC中初始化应用程序。添加(RBAC,app)到烧瓶扩展。在请求之前添加钩子以验证权限。
set_hook(hook)
设置挂钩,当权限被拒绝时调用如果你没有设置任何挂钩,Flask-RBAC将调用:
abort(403)
参数:
hook – Hook功能
set_role_model(model)
设置角色的自定义模型。
参数
model 角色模型
set_user_loader(loader)
设置用户加载程序,用于加载当前用户。一个例子:
from flask_login import current_user
rbac.set_user_loader(lambda: current_user)
参数:
loader - 当前用户功能。
set_user_model(model)
设置用户的自定义模型
参数: model - 用户模型
Flask.ext.rbac.model.RoleMixin
class flask_rbac.model.RoleMixin(name=None)
这提供了Flask-RBAC希望角色模型具有的方法的实现。
参数:
name - 角色的名称。
add_parent(parent)
将父级添加到此角色,并将角色本身添加到父级的子级集。如果需要,你应该覆盖这个功能。
例:
logged_user = RoleMixin('logged_user')
student = RoleMixin('student')
student.add_parent(logged_user)
参数:
parent - 要添加的父角色。
add_parents(*parents)
将父母添加到此角色。如果需要,也应该覆盖。例:
editor_of_articles = RoleMixin('editor_of_articles')
editor_of_photonews = RoleMixin('editor_of_photonews')
editor_of_all = RoleMixin('editor_of_all')
editor_of_all.add_parents(editor_of_articles, editor_of_photonews)
参数:
parents – Parents to add.
static get_by_name(name)
一个静态方法,用于返回具有输入名称的角色。
参数:
name - 角色的名称。
get_name()
返回此角色的名称
Flask.ext.rbac.model.UserMixin
class flask_rbac.model.UserMixin(roles=[])
这提供了Flask-RBAC希望用户模型具有的方法的实现。
参数: roles- 此用户的角色应该具有。
add_role(role)
向此用户添加角色。
add_roles(*roles)
向此用户添加角色。