Flask 学习 八 用户角色
角色在数据库中表示
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 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) # 如果不具备该权限,返回403错误码
return f(*args,**kwargs)
return decorated_function
return decorator def admin_required(f):
return permission_required(Permission.ADMINISTER)(f)
# 举例演示使用权限检查装饰器
from app.decorators import admin_required,permission_required
from ..models import Permission
from flask_login import login_required @main.route('/admin')
@login_required
@admin_required
def 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_processor
def 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))
Flask 学习 八 用户角色的更多相关文章
- Flask学习之五 用户登录
英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins 中文翻译地址:http:// ...
- Flask 学习 九 用户资料
资料信息 app/models.py class User(UserMixin,db.Model): #...... name = db.Column(db.String(64)) location ...
- Flask 学习 七 用户认证
使用werkzeug 实现密码散列 from werkzeug.security import generate_password_hash,check_password_hash class Use ...
- flask学习(八):页面跳转和重定向
1. 用处:在用户访问一些需要登录的页面的时候,如果用户没有登录,那么让页面重定向到登录页面 2. 实例 运行效果: 用户已登录,进入发布问答页面 用户未登录,跳转到登录页面
- 学习RBAC 用户·角色·权限·表
- Flask学习之六 个人资料和头像
英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-vi-profile-page-and-avatars ...
- SpringBoot学习- 10、设计用户角色权限表
SpringBoot学习足迹 前几节已经基本了解了SpringBoot框架常用的技术,其他的消息队列,定时器等技术暂时用不到,真正项目中如果基于微信系,阿里系开发的话,还要了解平台专用的技术知识,学习 ...
- Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理
这是本人第一次写,写的不好的地方还忘包含.写这个的主要原因是想通过这个来学习下EF的CodeFirst模式,本来也想用AngularJs来玩玩的,但是自己只会普通的绑定,对指令这些不是很熟悉,所以就基 ...
- 七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理
系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...
随机推荐
- css3动画结束捕捉事件整理
//捕捉webkitAnimationEnd事件 element.addEventListener('webkitAnimationEnd', end, false); //捕捉webkitTrans ...
- 在VCS仿真器中使用FSDB[转载]
来源:https://www.cnblogs.com/catannie/p/8099331.html FSDB(Fast Signal Database)是Verdi支持的文件格式,用于保存仿真产生的 ...
- [Luogu3066][USACO12DEC]逃跑的BarnRunning Away From…
题面 题目描述 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 输入格式: Line 1: 2 integers, N and L (1 <= N <= 2 ...
- 如何将生产环境的字段类型从INT修改为BIGINT
介绍 改变数据类型是一个看起来很简单的事情,但是如果表非常大或者有最小停机时间的要求,又该如何处理那?这里我提供一个思路来解决这个问题. 背景 在一个常规SQL Server heath检查中,使用s ...
- Mysql遇到 is marked as crashed and should be repaired 问题解决方法
遇到 找到mysql的安装目录的bin/myisamchk工具,在命令行中输入: myisamchk -c -r /var/lib/mysql/ambari/alert_current.MYI 问题解 ...
- 2018java平均工资,想转行学java的快点上车
很多人选择工作的原因很简单:要么有钱,要么自己开心,当然绝大多数人是既没有钱也不开心...(现实就是这么残酷).哪有钱多事少的活,请告诉我,我第一个去!!我想大部分人对java充满好奇的一个原因就是钱 ...
- VMware下安装centos7及网络配置
之前遇到过用虚拟机安装上centos7上不了网,昨天解决了,但是手抽删错了,把centos7误删了,今天就一起安装下. 首先打开VMware,我这里用的版本是VMware12,然后我们新建虚拟机 下一 ...
- Hadoop集群环境安装
转载请标明出处: http://blog.csdn.net/zwto1/article/details/45647643: 本文出自:[zhang_way的博客专栏] 工具: 虚拟机virtual ...
- Win 及 Linux 查找mac地址的方法
1. Windows系统中 - 调出cmd命令行 - 运行Getmac命令.命令行中输入: getmac /v /fo list 并按下回车键 - 查找物理地址.这是MAC地址的另一种描述方式.因为在 ...
- spark source code 分析之ApplicationMaster overview(yarn deploy client mode)
一直不是很清楚ApplicationMaster的作用,尤其是在yarn client mode和cluster mode的区别 网上有一些非常好的资料,请移步: https://blog.cloud ...