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 (三)— ...
随机推荐
- FJUT2017寒假训练二题解
A题 题意:让你找出唯一的一个四位数,满足对话时的要求. 思路:因为是4位数,可以直接从1000-9999遍历一遍,判断是否有唯一的数能满足所有条件,如果不是唯一的或者没有满足条件的数就输出Not s ...
- Openstack Pycharm 的远程调试
问题背景 最近再研究openstack cinder api的时候遇到了个问题:使用命令行调用API的时候,使用domain的token时,会产生一个错误,但是通过cinder的api都无法确定产生错 ...
- Linux IPMI 配置管理.md
DELL 服务器 user id 范围:1-16 可以修改用户名和密码 不允许用户名重复 当设置一个已存在的用户名时,无论user id在前或在后,修改密码会将该项用户名设置为空,enable会恢复成 ...
- 进入TP-Link路由器之后利用快捷键F12查看星号路由密码的方法
今天又破解了几个路由器,这两张图片是大多数路由器如TP-LINK路由器查看拨号圆点密码的方法.
- 读取超大Excel(39万行数据)
有个学长需要处理Excel数据,Excel数据共有39W,将数据读取后处理并导出数据.最开始尝试了 NPOI ,发现NPOI 并不能完成该项任务,随后尝试引用的com组件:Microsoft.Offi ...
- ServiceFabric极简文档-0. ServiceFabric简介
前言: 最近ServiceFabric开源了,大家热情都比较高,官方文档大而全,但快速入手不容易找到头绪.发几篇极简的文档,跟大家分享一下,顺便为Ray的ServiceFabric部署做一下铺垫.因为 ...
- 关于Roll A Ball实例练习记录
学习中不段进步! 游戏思路:通过键盘控制白色小球,让它"捡起"柠黄色方块,捡起一个加1分,全部捡起游戏胜利! 游戏对象: Ground:绿色地面 player: 小球 Obsta ...
- protobuf的下载、编译和使用
一 背景 工作中临时需要使用 protobuf v3.0.2 做消息格式转换,折腾了很久才搞定,这里特意做一个记录. 二 准备工作 全程使用的电脑为公司的win7 64位旗舰版,已经预先安装VS201 ...
- 笔记:I/O流-字符集
Java 库的 java.nio 包用 Charset 类统一了对字符集的转换,支付姐建立了两个字节Unicode码元序列与使用本地字符编码方式的字节序列之间的映射,Charset类使用的时由IANA ...
- React 系列文章(1): npm 手动搭建React 运行实例 (新手必看)
摘 要 刚接触React 开发, 在摸索中构建react 运行环境,总会遇到各种坑:本文,将用最短时间解决webpack+react 环境搭建问题. 1.如果你还没有React基础 看这里. 2.如果 ...