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') @staticmethod
def insert_role():
roles = {
'STAFF': (Permission.ONLY_QUERY, True),
'HIGH_STAFF': (Permission.ONLY_QUERY|
Permission.FORBID, False),
'LEADER': (Permission.ONLY_QUERY|
Permission.FORBID|
Permission.ASSIGN, False),
'ADMINISTATOR': (0x0f, False)
}#除了onlyquery之外,其他的都是模式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() def __repr__(self):
return '<Role %r>' % self.name
Permission类代码如下:
class Permission:
ONLY_QUERY = 0x01#仅查询
FORBID = 0x03#封号
ASSIGN= 0x07#分配行号
ADMINISTRATOR = 0x0f#这个权限要异或
2,授予用户权限:在User模型中添加role的属性
class User(UserMixin,db.Model):
__tablename__ = 'users'
id = db.Column(db.SmallInteger,primary_key=True,nullable=False)#这个字段必须是id,否则无法完成登录验证
username = db.Column(db.String(64))
password_hash = db.Column(db.String(128))
email = db.Column(db.String(64))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
config_content = config[os.getenv('FLASK_CONFIG') or 'default']
因为User模型有role的属性,可以通过User.role来获取Role数据库中的内容,所以我们的思路是直接通过这一特性进行操作,直接在User模型中的初始化方法中实现默认权限的赋予,是管理员给管理员权限,不是给默认的用户权限。
def __init__(self,**kwargs):
super(User,self).__init__(**kwargs)
#继承了父类的初始化方法,super等价于UserMixin
self.role = kwargs['role_id']
if self.role is None:
if self.email == self.config_content.ADMINS:
#验证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()
第4行是管理员为普通员工注册的时候提供的权限,如果是博客权限为空的用户,即刚注册的用户,可以删除第4行,若是用户冲了一个尊贵的会员就需要单独赋予权限了,所以我们可以在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.ADMINISTRATOR)
3.2 将上面方法写入修饰函数中
#encoding:utf8 from functools import wraps
from flask import abort
from flask_login import current_user
from app.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.ADMINISTRATOR)(f)
3.3 用修饰函数对有权限要求的路由进行修饰:
@main.route('/forbid',methods=['GET','POST'])
@login_required
@permission_required(Permission.FORBID)
def forbid():
return 'Hello World'
4新用户注册:
在view中添加如下代码:
##注册
@main.route('/register',methods=['GET','POST'])
@login_required
@permission_required(Permission.ASSIGN)
def register():
form = RegisterationForm()
if form.validate_on_submit():
register_judge_obj = register_judge(form.permission.data)
role_id = register_judge_obj.judge()
user = User(username=form.username.data,password=form.password.data,email=form.email.data,role_id = role_id)
db.session.add(user)
db.session.commit()
return redirect(url_for('main.login'))
return render_template('register.html',form=form)
其中调用的register_judge类代码为
# -*- coding: utf-8 -*-
from app.models import Role class register_judge: def __init__(self,permission_id):
self.permission_id = permission_id def judge(self):
if self.permission_id == '':
role_id = Role.query.filter_by(id=4).first()
elif self.permission_id == '':
role_id = Role.query.filter_by(id=3).first()
elif self.permission_id == '':
role_id = Role.query.filter_by(id=1).first()
else:
role_id = Role.query.filter_by(default=True).first()
return role_id
实际操作过程中遇到的坑:
1,权限存入数据库中数值改变:它其实是以2进制的方式来处理的
0b00000001
0b00000010
0b00000100
0b10000000
如果只是第一个权限,它的值为1
如果是第二个权限(0b00000001|0b00000010)即0b00000011,即3
第三个(0b00000010|0b00000010|0b00000010)即0b00000111即7
以此类推
它并不是以10进制来计算的
2,装饰函数的理解存在问题。
Flask权限管理的更多相关文章
- Android权限管理之RxPermission解决Android 6.0 适配问题
前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...
- Android权限管理之Android 6.0运行时权限及解决办法
前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...
- Android权限管理之Permission权限机制及使用
前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...
- SpringMVC+Shiro权限管理【转】
1.权限的简单描述 2.实例表结构及内容及POJO 3.Shiro-pom.xml 4.Shiro-web.xml 5.Shiro-MyShiro-权限认证,登录认证层 6.Shiro-applica ...
- Android6.0运行时权限管理
自从Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifest设置就可以任意获取权限,而是更加的注重用户的隐私和体验,不会再强迫用户因拒绝不该拥有的权限而导致的无法安装 ...
- Oracle 表空间和用户权限管理
一. 表空间 Oracle数据库包含逻辑结构和物理结构. 数据库的物理结构指的是构成数据库的一组操作系统文件. 数据库的逻辑结构是指描述数据组织方式的一组逻辑概念以及它们之间的关系. 表空间是数据库逻 ...
- [Django]用户权限学习系列之权限管理界面实现
本系列前三章: http://www.cnblogs.com/CQ-LQJ/p/5604331.htmlPermission权限基本操作指令 http://www.cnblogs.com/CQ-LQJ ...
- [Django]用户权限学习系列之设计自有权限管理系统设计思路
若在阅读本片文章遇到权限操作问题,请查看本系列的前两章! http://www.cnblogs.com/CQ-LQJ/p/5609690.html和http://www.cnblogs.com/CQ- ...
- 我的MYSQL学习心得(十三) 权限管理
我的MYSQL学习心得(十三) 权限管理 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...
随机推荐
- python常用BIF汇总
append():在列表末尾增加一个数据项:例如a.append('hello') pop():用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值:例如a.pop() extend(): ...
- /etc/security/limits.conf
ulimit 命令用来限制系统用户对 shell 资源的访问,但只是临时生效,想要永久生效需要配置 /etc/security/limits.conf 文件,语法及常见配置如下: [root@loca ...
- excel——之锁定表头不可编辑
前言: 设置excel表头不可编辑功能.效果如下: 这就意味着,不可随意更改表头数据,除非你有密码. 过程: 1.先随意右键打开一个单元格,查看其中的“设置单元格属性”,即 2.在选中想要编辑的那些数 ...
- 2.6 CMMI2级——供应商协议管理(Supplier Agreement Management)
做软件开发的,不免要购买一些软硬件.软件可能是中间件.控件.插件.组件等,硬件可能是一些服务器.PDA.单片机等.只要稍微复杂的项目,都不可避免的会有采购的问题,就算目前没有采购,以后也会不可避免.另 ...
- Android ImageResizer:inSampleSize
import android.annotation.TargetApi; import android.content.Context; import android.content.res.Reso ...
- Java可视化JVM监控软件
jdk自带.jdk安装目录下 1.JConsole 选择 不安全 可用不多 2.VisualVM
- Windows 2008 server R2安装.NET Framework4时提示“灾难性故障”
报错信息: 安装.NET Framework 4时,提示安装未成功,“灾难性故障”.服务器的操作系统是windows server 2008 R2. 查看系统日志时显示“无法安装 Windows 更 ...
- PHP pdf转化为图片(PNG)
/** * 将pdf文件转化为多张png图片 * @param string $pdf pdf所在路径 (/www/pdf/abc.pdf pdf所在的绝对路径) * @param string $p ...
- java如何发起https请求
1.写一个SSLClient类,继承至HttpClient import java.security.cert.CertificateException; import java.security.c ...
- Hive sql语法详解
Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的SQ ...