用户角色
1.Web程序成员可能包括管理员/内容发布员/普通用户/匿名用户等,每种角色对应着拥有不同的权限控制
2.对于只有普通用户/管理员分类,只需在用户模型中添加一个is_administrator布尔值即可,对于多角色可结合权限属性绑定实现
角色权限
0b00000001 |
0x01 |
关注其它用户 |
0b00000010 |
0x02 |
评论其它人文章 |
0b00000100 |
0x04 |
写文章 |
0b00001000 |
0x08 |
管理其他人发表的评论 |
0b10000000 |
0x80 |
管理网站 |
0b00000000 |
0x00 |
匿名用户,未登录的用户,应该只具有阅读文章 |
0b00000011 |
0x03 |
普通用户,应该只具有阅读文章,发布文章,评论文章和关注其他用户的权限,新用户的默认角色 |
0b00000111 |
0x07 |
协管用户,应该只具有阅读文章,发布文章,评论文章和关注其他用户,审查不当评论的权限 |
0b11111111 |
0xff |
管理用户,应该具有所有权限,包括修改其它用户所属角色的权限 |
FlaskWeb/app/models.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://my.oschina.net/pydevops/
# Purpose:
#
"""
from . import db, loginmanager
from flask import current_app
from flask_login import UserMixin
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from werkzeug.security import generate_password_hash, check_password_hash
@loginmanager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class Permission(object):
FOLLOW = 0x01
COMMENT = 0x02
WRITE_ARTICLES = 0x04
MANAGE_COMMENTS = 0x08
ADMINISTER_POWER = 0x80
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, nullable=False, index=True)
permission = db.Column(db.Integer)
default = db.Column(db.Boolean, default=False, index=True)
users = db.relationship('User', backref='role', lazy='dynamic')
@staticmethod
def insert_roles():
roles = {
'user': (
Permission.FOLLOW |
Permission.COMMENT |
Permission.WRITE_ARTICLES, True),
'manager': (
Permission.FOLLOW |
Permission.COMMENT |
Permission.WRITE_ARTICLES |
Permission.MANAGE_COMMENTS, False),
'administrator': (
Permission.ADMINISTER_POWER, False)
}
for cur_role in roles:
role = Role.query.filter_by(name=cur_role).first()
if not role:
role = Role(name=cur_role)
role.permission = roles[cur_role][0]
role.default = roles[cur_role][-1]
db.session.add(role)
db.session.commit()
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(64), unique=True, nullable=False, index=True)
username = db.Column(db.String(64), unique=True, nullable=False, index=True)
password_hash = db.Column(db.String(128), nullable=False)
is_confirmed = db.Column(db.Boolean, default=False)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
@property
def password(self):
raise AttributeError(u'password 不允许读取.')
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
def generate_confirm_token(self, expires_in=3600):
s = Serializer(current_app.config['SECRET_KEY'], expires_in=expires_in)
data = s.dumps({'confirm_id': self.id})
return data
def verify_confirm_token(self, token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
data = s.loads(token)
except BaseException, e:
return False
if data.get('confirm_id') != self.id:
return False
self.is_confirmed = True
db.session.add(self)
db.session.commit()
return True
说明:如上创建了一个Permission权限类,类权限属性用8位二进制表示权限,在Role类中增加2个字段,permission和default,分别标识角色权限和是否为默认角色,由于二进制方便与计算,所以很容易计算角色权限,insert_roles()并不直接创建新角色对象,而是通过角色名查找现有角色,如果有则更新,否则才会创建
注意:匿名角色不需要在数据库中体现,这个角色的作用是为了表示不在数据库中的用户
FlaskWeb/manager.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://my.oschina.net/pydevops/
# Purpose:
#
"""
from app import db as _db
from app import create_app
from config import config
from app.models import Role
from flask_script import Manager
app = create_app()
manager = Manager(app)
@manager.command
def db(command):
if command == 'init':
_db.create_all()
Role.insert_roles()
if command == 'drop':
_db.drop_all()
if __name__ == '__main__':
manager.run()
说明:由于更改了数据模型,需要先python manager.py db drop然后python manager.py db init,如上将Role对象引用进来在外部调用init时,将会将我们生成的角色写进数据库,后期增加角色也非常方便
来源:oschina
链接:https://my.oschina.net/u/2612057/blog/702309