tornado簡單實現基於角色的權限管理

用戶表、角色表、權限表、權限分組表

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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章