用戶表、角色表、權限表、權限分組表
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()