用户表、角色表、权限表、权限分组表
from sqlalchemy import Column,Integer, String, Text, ForeignKey,
DateTime,Boolean,SMALLINT,BigInteger,Table # 定义字段
from app.models.connect import Base
from sqlalchemy.orm import relationship
# Create your models here.
class BaseModel:
id_delete = Column(Boolean,default=False)
createdAt = Column(DateTime, nullable=False) # 创建时间
updatedAt = Column(DateTime, nullable=False) # 修改时间
#用户to角色表(多对多中间表)
User2Roles = Table('users2roles', Base.metadata,
Column("user_id", Integer, ForeignKey("users.id")),
Column("role_id", Integer, ForeignKey("roles.id"))
)
#角色to权限表(多对多中间表)
Role2Permiss = Table("roles2permiss", Base.metadata,
Column("role_id", Integer, ForeignKey("roles.id")),
Column("permiss_id", Integer, ForeignKey("permissions.id"))
)
# 定义会员数据模型
class Users(BaseModel,Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True) # 编号
name = Column(String(20), nullable=False, unique=True) # 昵称
pwd = Column(String(255), nullable=False) # 密码
email = Column(String(100), nullable=False, unique=True) # 邮箱
phone = Column(String(11), nullable=False, unique=True) # 手机
sex = Column(SMALLINT, nullable=True) # 性别
face = Column(String(100), nullable=True) # 头像
info = Column(String(600), nullable=True) # 个性签名
roles = relationship("Roles",secondary="users2roles",backref="users")
#定义角色模型
class Roles(BaseModel,Base):
__tablename__= "roles"
id = Column(Integer,primary_key=True)
name = Column(String(32))
permissions = relationship("Permissions",secondary="roles2permiss",backref="roles")
#定义权限模型
class Permissions(BaseModel,Base):
__tablename__= "permissions"
id =Column(Integer,primary_key=True)
name = Column(String(32))
#url = Column(String(32))
code = Column(String(32))
permissgroup_id = Column(Integer,ForeignKey("permissgroup.id"))
permiss_group = relationship("PermissionGroup", backref='permissions')
#定义权限分组模型
class PermissionGroup(Base):
__tablename__= "permissgroup"
id = Column(Integer,primary_key=True)
caption = Column(String(32))
##创建表
if __name__ =="__main__":
Base.metadata.create_all() ##去数据库里面创建所有的表
那么在视图中如何使用呢?
首先定义一个权限认证类
rabc.py
from app.tools.orm import ORM
from app.models.model import Users
#定义权限认证类
class PermissionsMixin:
@classmethod
def get_all_permissions(cls,name):
session = ORM.db()
permission_set = set()
# 事务处理的逻辑
try:
if name:
roles = session.query(Users).filter(Users.name == name).first().roles
print('roles:%s'%roles)
for r in roles:
for p in r.permissions:
permission_set.add(p.code)
print('permission_set:%s'%permission_set)
return permission_set
except Exception as e:
session.rollback() # 如果发生异常直接回滚
else:
session.commit() # 没有发生异常直接提交
finally:
session.close() # 无论是否发生异常最后一定关闭会话
@classmethod
def has_perm(cls,perm,name):
print(perm)
print(name)
permission_set = cls.get_all_permissions(name)
print(permission_set)
if perm in permission_set:
return True
else:
return False
views
import tornado.web
from app.tools.orm import ORM
from app.tools.demo import PermissionsMixin as permiss
class IndexHandle(tornado.web.RequestHandler):
# 不同请求,对应不同的权限,实现对不同请求权限的分化
permission_required = {
'get': 'news_add',
'put': 'news_update',
'delete': 'news_delete',
}
def prepare(self):
# 拿到你的分组权限
perms = self.permission_required
name = "张三"
if not permiss.has_perm(perms[self.request.method.lower()],name):
return self.write("对不起,没有权限")
def get(self):
self.write("请求成功")
def post(self):
pass
可以把上面的prepare写到一个公共类中:
common.py
import tornado.web
from app.tools.rbac import PermissionsMixin as permiss
from tornado.web import Finish
class CommonHandler(tornado.web.RequestHandler):
def prepare(self):
#之前进行登录认证
#未登录就重定向到登录路由
# 拿到你的分组权限
perms = self.permission_required
name = "王五"
if not permiss.has_perm(perms[self.request.method.lower()],name):
raise Finish({
"errno":"0","msg":"没有权限"})
views.py
from app.tools.common import CommonHandler
class IndexHandle(CommonHandler):
# 不同请求,对应不同的权限
#命名规则:app名_get/update/delete/add
permission_required = {
'get': 'news_get',
'put': 'news_update',
'delete': 'news_delete',
}
def get(self):
self.write({
"errno":"1","msg":"请求成功"})
def post(self):
pass
orm.py
from sqlalchemy import create_engine # 导入创建引擎
from sqlalchemy.orm import sessionmaker # 创建会话工具
from app.configs import mysql_configs # 导入连接配置
# 创建会话,操作数据表要通过会话操作
class ORM:
@classmethod
def db(cls):
link = "mysql+pymysql://{db_user}:{db_pwd}@{db_host}:{db_port}/{db_name}?charset=utf8".format(
**mysql_configs
)
# 创建连接引擎,encoding编码,echo是[True]否[False]输出日志
engine = create_engine(
link,
encoding="utf-8",
echo=False,
pool_size=100,
pool_recycle=10,
connect_args={
'charset': "utf8"}
)
# 创建用于操作数据表的会话
Session = sessionmaker(
bind=engine,
autocommit=False,
autoflush=True,
expire_on_commit=False
)
# autocommit,自动提交,True[开启],False[关闭],采用手动的方式,自己写事务处理的逻辑
# autoflush,自动刷新权限,True[开启]
return Session()