app/models.py

  1. class Role(db.Model):
  2. __tablename__ = 'roles'
  3. id = db.Column(db.Integer, primary_key=True)
  4. name = db.Column(db.String(64), unique=True)
  5. default = db.Column(db.Boolean, default=False, index=True)
  6. permissions = db.Column(db.Integer)
  7. users = db.relationship('User', backref='role', lazy='dynamic')

程序的权限

FOLLOW         关注用户              0x01

COMMET         在他人文章中发表评论  0x02

WRITE_ARTICLES     写文章         0x04

MODERATE_COMMENTS    管理他人发表的评论   0x08

ADMINISTER        管理员权限       0x80

  1. class Permission:
  2. FOLLOW = 0x01
  3. COMMENT = 0x02
  4. WRITE_ARTICLES = 0x04
  5. MODERATE_COMMENTS = 0x08
  6. ADMINISTER = 0x80

列出了要支持的用户角色以及定义角色使用的权限位

用户角色

匿名        0x00      未登录的用户,在程序中只有阅读权限

用户        0x07      具有发表文章,发表评论和关注其他用户的权限。这是新用户的默认角色

协管员       0x0f       增加审查不当评论的权限

管理员       0xff       具有所有权限,包括修改其他用户所属角色的权限

app/models.py:在数据库中创建角色

  1. class Role(db.Model):
  2. __tablename__ = 'roles'
  3. id = db.Column(db.Integer, primary_key=True)
  4. name = db.Column(db.String(64), unique=True)
  5. default = db.Column(db.Boolean, default=False, index=True)
  6. permissions = db.Column(db.Integer)
  7. users = db.relationship('User', backref='role', lazy='dynamic')
  8.  
  9. @staticmethod
  10. def insert_roles():
  11. roles = {
  12. 'User': (Permission.FOLLOW |
  13. Permission.COMMENT |
  14. Permission.WRITE_ARTICLES, True),
  15. 'Moderator': (Permission.FOLLOW |
  16. Permission.COMMENT |
  17. Permission.WRITE_ARTICLES |
  18. Permission.MODERATE_COMMENTS, False),
  19. 'Administrator': (0xff, False)
  20. }
  21. for r in roles:
  22. role = Role.query.filter_by(name=r).first()
  23. if role is None:
  24. role = Role(name=r)
  25. role.permissions = roles[r][0]
  26. role.default = roles[r][1]
  27. db.session.add(role)
  28. db.session.commit()

这个Role表添加了一个静态方法,执行insert_roles函数会创建三个name,分别是用户,协管员和管理员

赋予角色:

app/models.py

  1. class User(UserMixin,db.Model):
  2. __tablename__ = 'users'
  3. id = db.Column(db.Integer, primary_key=True)
  4. email = db.Column(db.String(64),unique=True,index=True)
  5. username = db.Column(db.String(64), unique=True,index=True)
  6. role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
  7. password_hash = db.Column(db.String(128))
  8.  
  9. def __init__(self,**kwargs):
  10. super(User,self).__init__(**kwargs)
  11. if self.role is None:
  12. if self.email == current_app.config['FLASKY_ADMIN']:
  13. self.role = Role.query.filter_by(permission=0xff).first()
  14. if self.role is None:
  15. self.role = Role.query.filter_by(default=True).first()

User表的方法是:如果用户没有设置权限,用户的邮箱等于配置中设置的管理员邮箱,就设置为管理员权限,用户的权限为空,则设置为普通用户

角色验证

app/models.py:检查用户是否有指定的权限

  1. class User(UserMixin,db.Model):
  2.  
  3. #...
  4.  
  5. def can(self, permissions):
  6. return self.role is not None and \
  7. (self.role.permissions & permissions) == permissions
  8.  
  9. def is_administrator(self):
  10. return self.can(Permission.ADMINISTER)

can()方法在请求和赋予角色这两种权限之间进行位与操作。如果角色中包含请求的所有权限位,则返回True ,表示允许用户执行此项操作。

is_administrator()方法用来检车管理员权限

  1. from flask_login import AnonymousUserMixin
  1. class AnonymousUser(AnonymousUserMixin):
  2. def can(self,permissions):
  3. return False
  4.  
  5. def is_administraror(self):
  6. return False
  7.  
  8. login_manager.anonymous_user = AnonymousUser

 这个类用来检查匿名用户的权限

app/decorators.py:检查用户权限的自定义修饰器

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

这两个修饰器都使用了Python标准库中的functools包,如果用户不具有指定权限,则返回403错误码,即HTTP“禁止”错误。要添加一个403错误页面

以下的例子就是将上面的装饰器,用在了路由功能里面,针对一些页面设置了权限

  1. from decorators import admin_required, permission_required
  2. from .models import Permission
  3. @main.route('/admin')
  4. @login_required
  5. @admin_required
  6. def for_admins_only():
  7. return "For administrators!"
  8.  
  9. @main.route('/moderator')
  10. @login_required
  11. @permission_required(Permission.MODERATE_COMMENTS)
  12. def for_moderators_only():
  13. return "For comment moderators!"

  

在模板中可能也需要检查权限,所以Permission 类为所有位定义了常量以便于获取。为了避免每次调用render_template() 时都多添加一个模板参数,可以使用上下文处理器。上下文处理器能让变量在所有模板中全局可访问。

app/main/__init__.py:把Permission类加入模板上下文

  1. @main.app_context_processor
  2. def inject_permissions():
  3. return dict(Permission=Permission)

 

tests/test_user_models.py:角色和权限的单元测试

  1. #...
  2.  
  3. def test_roles_and_permissions(self):
  4. Role.insert_roles()
  5. u = User(email='1808863623@qq.com',password='cat')
  6. self.assertTrue(u.can(Permission.WRITE_ARTICLES))
  7. self.assertFalse(u.can(Permission.MODERATE_COMMENTS))
  8.  
  9. def test_anonymous_user(self):
  10. u = AnonymousUser()
  11. self.assertFalse(u.can(Permission.FOLLOW))

  

Flask-用户角色及权限的更多相关文章

  1. WordPress用户角色及其权限管理编辑插件:User Role Editor汉化版

    如果Wordpress默认的用户角色及权限不能满足您的需求,又觉得修改代码编辑用户权限太麻烦.那不妨试试User Role Editor,Wordpress用户角色及其权限管理编辑插件. User R ...

  2. SpringSecurity 自定义用户 角色 资源权限控制

    SpringSecurity 自定义用户 角色 资源权限控制 package com.joyen.learning.security; import java.sql.ResultSet; impor ...

  3. RabbitMQ用户角色及权限控制

    RabbitMQ的用户角色分类:none.management.policymaker.monitoring.administrator RabbitMQ各类角色描述:none不能访问 managem ...

  4. RabbitMQ用户角色及权限控制(转)

    转载至:https://blog.csdn.net/awhip9/article/details/72123257 2017年05月15日 10:39:26 awhip9 阅读数:3538   ### ...

  5. RabbitMQ用户角色及权限控制 -2

    1.RabbitMQ的用户角色分类: none.management.policymaker.monitoring.administrator none 不能访问 management plugin ...

  6. RabbitMQ用户角色及权限控制(不错)

    ########################用户角色####################### RabbitMQ的用户角色分类:none.management.policymaker.moni ...

  7. Flask 学习 八 用户角色

    角色在数据库中表示 app/models.py class Role(db.Model): __tablename__='roles' id = db.Column(db.Integer,primar ...

  8. SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建

    SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建 技术栈 : SpringBoot + shiro + jpa + freemark ,因为篇幅原因,这里只 ...

  9. Oracle 用户、角色、权限(系统权限、对象权限)的数据字典表

    1 三者的字典表 1.1 用户 select * from dba_users; select * from all_users; select * from user_users; 1.2 角色 s ...

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

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

随机推荐

  1. java wait(),notify(),notifyAll()

    wait()的作用是使当前执行代码的线程进行等待,此方法是Object类的方法,该方法用来将当前线程置入“预执行队列”中,并且在wait()所带的代码处停止执行,直到接到通知或被中断位置.在调用wai ...

  2. 使用CRA开发的基于React的UI组件发布到内网NPM上去

    前言:构建的ES组件使用CNPM发布内网上过程 1. 使用Create-React-APP开的组件 如果直接上传到NPM,你引用的时候会报: You may need an appropriate l ...

  3. Spring 设计原则

    Spring 框架有四大原则(Spring所有的功能和设计和实现都基于四大原则): 1. 使用POJO进行轻量级和最小侵入式开发. 2. 通过依赖注入和基本接口编程实现松耦合. 3. 通过AOP和基于 ...

  4. CSS3学习-用CSS制作立体导航栏

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. session会话

    jsp会话篇session: package com.log; import java.io.IOException; import java.util.ArrayList; import java. ...

  6. vim的命令

    下面是从一个博客里摘抄出来的, 供自己学习使用.   在命令状态下对当前行用== (连按=两次), 或对多行用n==(n是自然数)表示自动缩进从当前行起的下面n行.你可以试试把代码缩进任意打乱再用n= ...

  7. [Oracle 视图] ALL_OBJECTS

    ALL_OBJECTS ALL_OBJECTS describes all objects accessible to the current user. ALL_OBJECTS描述当前用户的可访问的 ...

  8. fiddler设置只抓取某一域名请求

    简单易懂~

  9. 进度条插件使用demo

    1.下载地址: http://down.htmleaf.com/1502/201502031710.zip 2.效果图: 3.HTML代码:其中80设置当前所占百分比,即蓝色部分比例:注意引入必须的j ...

  10. 将Java应用部署到SAP云平台neo环境的两种方式

    方法1 - 使用Eclipse Eclipse里新建一个服务器: 服务器类型选择SAP Cloud Platform: 点Finish,成功创建了一个Server: Eclipse里选择要部署的项目, ...