博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask 学习 八 用户角色
阅读量:5161 次
发布时间:2019-06-13

本文共 4224 字,大约阅读时间需要 14 分钟。

 角色在数据库中表示

app/models.py

class Role(db.Model):    __tablename__='roles'    id = db.Column(db.Integer,primary_key=True)    name = db.Column(db.String(64),unique=True)    default = db.Column(db.Boolean,default=False,index=True) # 默认角色    permissions = db.Column(db.Integer)# 位标志,各个操作都对应一个位位置,能执行某项操作的角色,其位会被设为1    users = db.relationship('User',backref='role',lazy='dynamic')# 不加载记录,但是提供加载记录的查询

程序的权限 里面的位值。

权限常量app/models.py

class Permission:    FOLLOW=0x01    COMMENT=0x02    WRITE_ARTICLES=0x04    MODERATE_COMMENTS=0x08    ADMINISTER=0x80

用户角色

使用权限组织角色(不同角色拥有的权限利用位运算进行组合)

在Role类中写一个insert_roles方法来完成将角色添加到数据库中的操作

@staticmethod    def insert_roles():        roles = {            'User':(Permission.FOLLOW |                    Permission.COMMENT|                    Permission.WRITE_ARTICLES,True),            'Moderator':(Permission.FOLLOW |                         Permission.COMMENT |                         Permission.WRITE_ARTICLES |                         Permission.MODERATE_COMMENTS,False),            'Administrator':(0xff,False)        }        for r in roles:            role = Role.query.filter_by(name=r).first()# 先根据角色名查找现有的角色,然后再更新            if role is None:# 如果没有该角色名时才会创建新角色                role=Role(name=r) # 创建新角色            role.permissions=roles[r][0] # 设置该角色对应的权限            role.default=roles[r][1] # 设置该角色对应权限的默认值            db.session.add(role) # 添加到数据库        db.session.commit() # 提交数据库

赋予角色

app/models.py

管理员的管理员角色保存在设置变量FLASK_ADMIN中的电子邮件地址识别,只要这个电子邮件出现注册请求,就会被正确赋予角色

class User(UserMixin,db.Model):    def __init__(self,**kwargs):        super(User,self).__init__(**kwargs)# 调用父类的构造函数        if self.role is None: # 如果创建父类对象之后还没有定义角色            if self.email==current_app.config['FLASKY_ADMIN']:# 根据电子邮件地址                self.role=Role.query.filter_by(permissions=0xff).first() # 设置其为管理员            if self.role is None: # 或者设置为默认角色                self.role=Role.query.filter_by(default=True).first()

角色认证

为了简化角色和权限的实现过程,在User中添加一个辅助方法,检查是否有正确权限

from flask_login import UserMixin,AnonymousUserMixin # 匿名用户角色class User(UserMixin,db.Model):    #。。。。        def can(self,permissions):        # 在请求和赋予角色这两种权限进行位的“与”运算,如果成立,则允许用户执行此项操作        return self.role is not None and \               (self.role.permissions & permissions)==permissions     def is_administrator(self):# 认证为管理员角色判断        return self.can(Permission.ADMINISTER)class AnonymousUser(AnonymousUserMixin):    def can(self, permissions):        return False    def is_administrator(self):        return False# 用户未登录时current_user的值,并且不用用户登陆即可检查用户权限login_manager.anonymous_user=AnonymousUser

让视图函数只对具有特定权限的用户开放,可以自定义装饰器,一个检查常规权限,一个检查管理员权限

app/decorators.py

from flask import abortfrom flask_login import current_userfrom app.models import Permissiondef permission_required(permission):    def decorator(f):        @wraps(f)        def decorated_function(*args,**kwargs):            if not current_user.can(permission):                abort(403) # 如果不具备该权限,返回403错误码            return f(*args,**kwargs)        return decorated_function    return decoratordef admin_required(f):    return permission_required(Permission.ADMINISTER)(f)
# 举例演示使用权限检查装饰器from app.decorators import admin_required,permission_requiredfrom ..models import Permissionfrom flask_login import login_required@main.route('/admin')@login_required@admin_requireddef for_admins_only():    return 'For administrators'@main.route('/moderator')@login_required@permission_required(Permission.MODERATE_COMMENTS)def for_moderator_only():    return 'For comment moderator'

在模板中也需要检查权限,所以Permission类为所有 位 定义了常量以便获取,为了避免每次调用render_template()多添加一个模板参数,可以使用上下文管理器,让变量在所有模板中全局访问

app/main/__init__.py

@main.app_context_processordef inject_permissions():    return dict(Permission=Permission)

新添加角色和权限在单元测试中测试

test/test_user_model.py

class UserModelTestCase(unittest.TestCase):    def test_roles_and_permissions(self):        Role.insert_roles()        u = User(email='join12@example.com',password='cat')        self.assertTrue(u.can(Permission.WRITE_ARTICLES))        self.assertFalse(u.can(Permission.MODERATE_COMMENTS))    def test_anonymous_user(self):        u=AnonymousUser()        self.assertFalse(u.can(Permission.FOLLOW))

 

转载于:https://www.cnblogs.com/Erick-L/p/6892313.html

你可能感兴趣的文章
WPF DataGrid格式化数字类型
查看>>
Android 指定(后缀名)格式文件扫描
查看>>
Go-导入包(点操作)
查看>>
flask sqlalchemy联合wtf-form表单 查询需要的值是否存在
查看>>
hibernate坑边闲话
查看>>
工作原理
查看>>
java排序方法中的选择排序方法
查看>>
获取用户登陆所在的ip及获取所属信息
查看>>
Xcode 官方全版本下载 从xcode3.2到xcode4.5.2
查看>>
SharePoint 2010 文档管理系列
查看>>
15个常用的javaScript正则表达式
查看>>
Android.mk用法详解
查看>>
.net core项目初建
查看>>
配置IIS使用Python
查看>>
Python内置方法
查看>>
caffe python API
查看>>
398. Random Pick Index随机pick函数
查看>>
Design Pattern --- Factory Method
查看>>
遗传算法—Survival of the Fittest: Natural Selection with Windows Forms
查看>>
BUAA_OO_博客作业一
查看>>