角色在数据库中表示

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 学习 八 用户角色的更多相关文章

  1. Flask学习之五 用户登录

    英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins 中文翻译地址:http:// ...

  2. Flask 学习 九 用户资料

    资料信息 app/models.py class User(UserMixin,db.Model): #...... name = db.Column(db.String(64)) location ...

  3. Flask 学习 七 用户认证

    使用werkzeug 实现密码散列 from werkzeug.security import generate_password_hash,check_password_hash class Use ...

  4. flask学习(八):页面跳转和重定向

    1. 用处:在用户访问一些需要登录的页面的时候,如果用户没有登录,那么让页面重定向到登录页面 2. 实例 运行效果: 用户已登录,进入发布问答页面 用户未登录,跳转到登录页面

  5. 学习RBAC 用户·角色·权限·表

  6. Flask学习之六 个人资料和头像

    英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-vi-profile-page-and-avatars ...

  7. SpringBoot学习- 10、设计用户角色权限表

    SpringBoot学习足迹 前几节已经基本了解了SpringBoot框架常用的技术,其他的消息队列,定时器等技术暂时用不到,真正项目中如果基于微信系,阿里系开发的话,还要了解平台专用的技术知识,学习 ...

  8. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理

    这是本人第一次写,写的不好的地方还忘包含.写这个的主要原因是想通过这个来学习下EF的CodeFirst模式,本来也想用AngularJs来玩玩的,但是自己只会普通的绑定,对指令这些不是很熟悉,所以就基 ...

  9. 七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

随机推荐

  1. 【CJOJ1090】【洛谷1967】【NOIP2013】货车运输

    题面 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆 ...

  2. [BZOJ1002] [FJOI2007] 轮状病毒 (数学)

    Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Inpu ...

  3. Django的models实现分析

    1      引子 1.1     神奇的Django中的models 我们先来看一段在Django项目中常用的代码: 设置数据库models代码: class Students(models.Mod ...

  4. 使用非直接缓冲区与直接缓冲区进行文件的复制(基于Channel)

    一.利用通道完成文件的复制(非直接缓冲区)     long start = System.currentTimeMillis(); FileInputStream fis = new FileInp ...

  5. Mysql遇到 is marked as crashed and should be repaired 问题解决方法

    遇到 找到mysql的安装目录的bin/myisamchk工具,在命令行中输入: myisamchk -c -r /var/lib/mysql/ambari/alert_current.MYI 问题解 ...

  6. IE浏览器右键菜单插件开发(下篇)——如何用c#安装、卸载IE右键插件

    建立Installer安装类,如图: 代码如下: using Microsoft.Win32; using ResourceShare.UserClient.Common; using System; ...

  7. Hive数据仓库笔记(二)

    分区和桶:   分区:可以提高查询的效率,只扫描固定范围数据,不用全部扫描 CREATE TABLE logs (ts BIGINT, lineSTRING) PARTITIONED BY (dt S ...

  8. Java反射总结

    一. 获取Class对象的3种方法: 1. Class.forName("");例如:Class.forName("java.lang.String"); 2. ...

  9. webpack安装入门

    这两天心血来潮,突然想研究下webpack,花了一天时间,看网上有很多教程,不过发现安装的都是比较老的版本.后来发现还是我太年轻了,找技术播客还不如找官方网站.下面是一个webpack的官方网站,里面 ...

  10. maven项目与普通项目的区别

    maven项目 1:创建方式不同 (web项目举例) 第一种: 第二种: 2:目录结构  稍有不同 3:Pom文件 添加依赖信息,需要那个jar包的时候  加入哪个jar包的依赖,要不然无法使用这个j ...