Flask学习之八——用户角色

介绍的用户角色实现方式结合了分立的角色和权限: 即赋予用户分立的角色,但角色使用权限定义。

1. 角色在数据库中的表示

采用如下的权限

上述权限采用如下代码表示
app/models.py:权限常量

class Permission:
    FOLLOW = 0x01
    COMMENT = 0x02
    WRITE_ARTICLES = 0x04
    MODERATE_COMMENTS = 0x08
    ADMINISTER = 0x80

采用如下的用户角色

在Role模型中增加跟权限有关的列

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)
    users = db.relationship(‘User‘, backref=‘role‘, lazy=‘dynamic‘)

只有一个角色的default字段要设为True,其他都设为False。
用户注册时,其角色会被设为默认角色。

permissions字段其值是一个整数,表示位标志。用来表示角色对应的权限操作

然后在Role类中添加一个类方法,完成添加用户角色的操作

app/models.py: 在数据库中添加用户角色

class Role(db.Model):
    #...
    @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()

nsert_roles() 函数并不直接创建新角色对象,而是通过角色名查找现有的角色,然后再进行更新。只有当数据库中没有某个角色名时才会创建新角色对象。
如此一来,如果以后更新了角色,就可以执行更新操作了。(要想更新角色,只要修改roles 字典,再运行函数即可。)

2. 赋予用户角色

app/models.py: 定义默认的用户角色

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()
            else:
                self.role = Role.query.filter_by(default=True).first()

User 类的构造函数首先调用基类的构造函数。如果创建基类对象后还没定义角色,则根据电子邮件地址觉得将其设为管理员还是默认角色

3. 角色验证

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

from flask.ext.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

login_manager.anonymous_user = AnonymousUser

can()方法在角色所拥有的权限以及要比较的权限之间进行位与操作。如果角色中包含要比较的权限,则返回True,表示允许用户执行此项操作

出于一致性考虑,还定义了 AnonymousUser 类,并实现了 can() 方法和 is_administrator()方法。
这个对象继承自 Flask-Login 中的 AnonymousUserMixin 类,并将其设为用户未登录时current_user 的值。
这样程序不用先检查用户是否登录,就能自由调用 current_user.can() 和current_user.is_administrator()。

如果想让某些视图函数只对具有特定权限的用户开发,可自定义修饰器实现

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

from functools import warps
from flask import abort
from flask.ext.login import current_user
from .models import Permission 

def permission_required(permission):
    def decorator(func):
        @warps(func)
        def warpper(*args, **kwargs):
            if not current_user.can(permission):
                abort(403)
            return func(*args, **kwargs)
        return wrapper
    return decorator

def admin_required(func):
    return permission_required(Permission.ADMINISTER)(func) 

举两个例子使用这些装饰器

from decorators import admin_required, permission_required
from .models import Permission

@main.route(‘/admin‘)
@login_required
@admin_required
def for_admins_only():
    return ‘For Administrator‘

@main.route(‘/moderator‘)
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def for_moderators_only():
    return ‘For comment moderator‘

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

app/main/__init__.py: 把Permission类加入模板上下文
@main.app_context_processor
def inject_permissions():
    return dict(Permission=Permission)

2015-05-24

时间: 2024-10-09 14:19:08

Flask学习之八——用户角色的相关文章

Flask学习之五 用户登录

英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins 中文翻译地址:http://www.pythondoc.com/flask-mega-tutorial/userlogin.html 开源中国社区:http://www.oschina.net/translate/the-flask-mega-tutorial-part-v-user-logins 备注:我是三个一起看的,有些

Flask学习之六——用户认证

1. 密码安全性 使用Werkzeug实现密码hash generate_password_hash(password, method, salt_length) 将原始密码作为输入,以字符串形式输出密码的hash值,输出的值可保存在用户数据库中.method 和 salt_length的默认值就能满足大多数需求. check_password_hash(hash, password) 将数据库中取回的密码hash和用户输入的密码比较,如果密码正确则返回Trueapp/models.py:在Us

Flask学习之八 关注、联系人和好友

英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-viii-followers-contacts-and-friends 中文翻译地址:http://www.pythondoc.com/flask-mega-tutorial/followers.html 开源中国社区:http://www.oschina.net/translate/the-flask-mega-tutorial-part-viii-f

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

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

英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-vi-profile-page-and-avatars 中文翻译地址:http://www.pythondoc.com/flask-mega-tutorial/profile.html 开源中国社区:http://www.oschina.net/translate/the-flask-mega-tutorial-part-vi-profile-page-

Flask学习之九——用户信息界面

1. 数据库中添加用户信息 app/models.py: 添加用户资料列 class User(UserMixin, db.Model): #... name = db.Column(db.String(64)) location = db.Column(db.String(64)) about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datatime.utcnow) last_seen

t3用户-角色-权限hibernate经典配置

[java] view plain copy print? 用户-角色-权限hibernate经典配置. [java] view plain copy print? 既然有人问起,我就写下说明吧.在文章中间的配置文件那里.权当回忆一下,也帮助更多人.这是以前学校时写的,没有注释.都是贴的代码笔记.看到的莫要见怪.欢迎学习交流. [java] view plain copy print? [java] view plain copy print? 首先是三个实体类: [java] view pla

Flask框架获取用户IP地址的方法

本文实例讲述了python使用Flask框架获取用户IP地址的方法.分享给大家供大家参考.具体如下: 下面的代码包含了html页面和python代码,非常详细,如果你正使用Flask,也可以学习一下最基本的Flask使用方法. python代码如下: from flask import Flask, render_template, request # Initialize the Flask application app = Flask(__name__) # Default route,

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

注:本文为学习摘录,原文地址为:http://www.cnblogs.com/powertoolsteam/p/MVC_five.html 目录 实验22——添加页脚 实验23——实现用户角色管理 实验24——实现项目外观一致性 实验25——使用Action  过滤器让页眉和页脚代码更有效 总结 实验22——添加页脚 在本实验中,我们会在Employee 页面添加页脚,通过本实验理解分部视图. 什么是“分部视图”? 从逻辑上看,分部视图是一种可重用的视图,不会直接显示,包含于其他视图中,作为其视