Flask-RBAC

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)
向此用户添加角色。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容