zoukankan      html  css  js  c++  java
  • flask 权限

    flask权限管理功能的实现

    权限管理功能的实现可以分为以下几个小块: 
    1,新建数据库表Role,里面包括id(Integer,主键)name(String),permission(Integer),default(boolean)。users是指向User模型的对外关系,反向赋给User模型一个role属性,这样就可以同郭User.role来访问Role模型,这样就创建了数据库之间的关系。模型里面还定义了一个静态方法(@staticmethod,可以直接通过类访问这个方法而不需要创建实例之后才能访问这个方法),它的作用是初始化Role数据表中的数据,数据库模型代码如下:

    class Role(db.Model):
        #定义Role的数据库模型
        __tablename__ = 'roles'
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(64), unique=True)  
        permissions = db.Column(db.Integer)
        default = db.Column(db.Boolean,default=False,index=True)
        users = db.relationship('User', backref='role', lazy='dynamic')
    
        def __repr__(self):
            return '<Role %r>' % self.name
        @staticmethod
        def insert_role():
        #这里需要注意的是‘|’的用法,以及python对各种进制的处理
            roles = {
                'User':(Permission.FOLLOW|
                        Permission.COMMENT|
                        Permission.WRITE_ARTICLES,True),
                'Moderate':(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()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    Permission类代码如下:

    
    class Permission():
        FOLLOW = 0x01
        COMMENT = 0x02
        WRITE_ARTICLES = 0x04
        MODERATE_COMMENTS = 0x08
        ADMINISTER = 0x80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2,授予用户权限:因为User模型有role的属性,可以通过User.role来获取Role数据库中的内容,所以我们的思路是直接通过这一特性进行操作,直接在User模型中的初始化方法中实现默认权限的赋予,是管理员给管理员权限,不是给默认的用户权限。

        def  __init__(self,**kwargs):
            super(User,self).__init__(**kwargs)
            #继承了父类的初始化方法,super等价于UserMixin
            if self.role is None:
                if self.email == current_app.config['FLASK_ADMIN']:
                #验证email是否为设置的管理员的email
                    self.role = Role.query.filter_by(permissions=0xff).first()
                if self.role is None:
                #如果经过了上一步权限还为空,就给个默认的User权限
                    self.role = Role.query.filter_by(default=True).first()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    以上只是针对于权限为空的用户,即刚注册的用户,若是用户冲了一个尊贵的会员就需要单独赋予权限了,所以我们可以在User模型里创建一个修改权限的方法,需要的时候调用就可以。 
    3,用它来对用户进行限制: 
    3.1,写一个用来判断用户权限的方法,传入用户需要的权限,进行验证,符合返回True,否则为False。这个方法在User模型里面:

        def can(self,permissions):
        #这个方法用来传入一个权限来核实用户是否有这个权限,返回bool值
            return self.role is not None and
            (self.role.permissions & permissions) == permissions
    
        def is_administrator(self):
        #因为常用所以单独写成一个方法以方便调用,其它权限也可以这样写
            return self.can(Permission.ADMINISTER)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.2 将上面方法写入修饰函数中

    #encoding:utf8
    
    from functools import wraps
    from flask import abort
    from flask_login import current_user
    from .models import Permission
    
    def permission_required(permission):
        def decorator(f):
            @wraps(f)
            def decorated_function(*args,**kwargs):
                if not current_user.can(permission):
                    abort(403)
                return f(*args, **kwargs)
            return decorated_function
        return decorator
    
    def admin_required(f):
        return permission_required(Permission.ADMINISTER)(f)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.3 用修饰函数对有权限要求的路由进行修饰:

    @auth.route('/admin')
    @admin_required
    def admin():
        return '你好,老公-_-'
    • 1
    • 2
    • 3
    • 4

    实际操作过程中遇到的坑: 
    1,权限存入数据库中数值改变:它其实是以2进制的方式来处理的

        0b00000001
        0b00000010
        0b00000100
        0b10000000
    如果只是第一个权限,它的值为1
    如果是第二个权限(0b00000001|0b00000010)即0b00000011,即3
    第三个(0b00000010|0b00000010|0b00000010)即0b00000111即7
    以此类推
    它并不是以10进制来计算的
  • 相关阅读:
    BFS POJ 2251 Dungeon Master
    DFS POJ 1321 棋盘问题
    构造 Codeforces Round #275 (Div. 2) C. Diverse Permutation
    线段树+树状数组+贪心 HDOJ 5338 ZZX and Permutations
    快速幂取模 POJ 3761 bubble sort
    矩阵快速幂 POJ 3070 Fibonacci
    矩阵快速幂 POJ 3735 Training little cats
    DP+矩阵快速幂 HDOJ 5318 The Goddess Of The Moon
    L2-001. 紧急救援(PAT)~最短路应用
    ~psd面试 求最长回文序列 DP求解
  • 原文地址:https://www.cnblogs.com/ithairy/p/9438259.html
Copyright © 2011-2022 走看看