[NewLife.XCode]角色權(quán)限
NewLife.XCode是一個有10多年歷史的開源數(shù)據(jù)中間件,支持nfx/netcore,由新生命團隊(2002~2019)開發(fā)完成并維護至今,以下簡稱XCode。
整個系列教程會大量結(jié)合示例代碼和運行日志來進行深入分析,蘊含多年開發(fā)經(jīng)驗于其中,代表作有百億級大數(shù)據(jù)實時計算項目。
開源地址:https://github.com/NewLifeX/X (求star, 864+)
前面講解了XCode的各種用法,這一章我們來講講內(nèi)置的Membership,同時也是XCode的第一標準示例!
設計背景
現(xiàn)代管理信息系統(tǒng)絕大部分采用BS架構(gòu),無一例外需要用戶角色權(quán)限的支持!
結(jié)合團隊諸多兄弟姐妹的經(jīng)驗,設計了一個大小適中的用戶權(quán)限系統(tǒng)Membership,目標是滿足80%的使用場景,并具備一定的擴展性。
Membership剛開始就采用了角色授權(quán)體系,每個用戶只有一種角色,角色擁有菜單資源權(quán)限集。
隨著Membership實用性日益增加,2015年初正式合并進入XCode,作為一個模塊存在。
2016年第二代魔方NewLife.Cube采用ASP.Net MVC5重構(gòu),讓Membership的榮譽達到了鼎峰!
在MVC中,每個Controller就是一個菜單資源,其下的Search/Detail/Insert/Update/Delete等Action作為角色在該菜單資源下的權(quán)限子項,保存在角色屬性數(shù)據(jù)中。
2018年為了增強魔方功能,在某些場景下支持單用戶多角色,且兼容已有系統(tǒng),用戶表增加RoleIDs字段,保存擴展角色,原來的RoleID作為主角色。
管理提供者
管理提供者接口 IManageProvider ,提供了Membership基本操作實現(xiàn)。
- 當前登錄用戶 GetCurrent、SetCurrent,靜態(tài)訪問 ManageProvider.User
- 查找用戶 FindByID、FindByName
- 注冊登錄注銷 Register、Login、Logout
- 當前用戶主機(訪問者IP)ManageProvider.UserHost
- IManageProvider 默認由XCode.Membership中的UserX/Role/Menu支持,如若用戶使用自己的用戶權(quán)限表,可重新實現(xiàn)該接口
用戶權(quán)限
用戶 UserX
用戶數(shù)據(jù)模型:
<Table Name="User" Description="用戶" RenderGenEntity="true"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Name" DataType="String" Master="True" Nullable="False" Description="名稱。登錄用戶名" /> <Column Name="Password" DataType="String" Description="密碼" /> <Column Name="DisplayName" DataType="String" Description="昵稱" /> <Column Name="Sex" DataType="Int32" Description="性別。未知、男、女" Type="SexKinds" /> <Column Name="Mail" DataType="String" Description="郵件" /> <Column Name="Mobile" DataType="String" Description="手機" /> <Column Name="Code" DataType="String" Description="代碼。身份證、員工編號等" /> <Column Name="Avatar" DataType="String" Length="200" Description="頭像" /> <Column Name="RoleID" DataType="Int32" Description="角色。主要角色" /> <Column Name="RoleIDs" DataType="String" Length="200" Description="角色組。次要角色集合" /> <Column Name="DepartmentID" DataType="Int32" Description="部門。組織機構(gòu)" /> <Column Name="Online" DataType="Boolean" Description="在線" /> <Column Name="Enable" DataType="Boolean" Description="啟用" /> <Column Name="Logins" DataType="Int32" Description="登錄次數(shù)" /> <Column Name="LastLogin" DataType="DateTime" Description="最后登錄" /> <Column Name="LastLoginIP" DataType="String" Description="最后登錄IP" /> <Column Name="RegisterTime" DataType="DateTime" Description="注冊時間" /> <Column Name="RegisterIP" DataType="String" Description="注冊IP" /> <Column Name="Ex1" DataType="Int32" Description="擴展1" /> <Column Name="Ex2" DataType="Int32" Description="擴展2" /> <Column Name="Ex3" DataType="Double" Description="擴展3" /> <Column Name="Ex4" DataType="String" Description="擴展4" /> <Column Name="Ex5" DataType="String" Description="擴展5" /> <Column Name="Ex6" DataType="String" Description="擴展6" /> <Column Name="UpdateUser" DataType="String" Description="更新用戶" /> <Column Name="UpdateUserID" DataType="Int32" Description="更新用戶" /> <Column Name="UpdateIP" DataType="String" Description="更新地址" /> <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="更新時間" /> <Column Name="Remark" DataType="String" Length="200" Description="備注" /> </Columns> <Indexes> <Index Columns="Name" Unique="True" /> <Index Columns="RoleID" /> <Index Columns="UpdateTime" /> </Indexes> </Table>
常用字段有ID、用戶名和密碼,登錄注冊相關(guān)信息;
角色RoleID、RoleIDs用于實現(xiàn)權(quán)限集控制;
部分場景需要郵箱Mail、手機Mobile或者工號Code登錄;
如果仍然不能滿足要求,可以考慮使用Ex1~Ex6等擴展字段。
常用功能點:
- 初始化時,如果數(shù)據(jù)表為空,自動插入admin/admin用戶賬號,角色是“管理員”
- 支持注冊登錄,使用MD5保存密碼
- 支持編號查詢FindByID和名稱查詢FindByName,分別采用了對象緩存和對象從鍵,輕松實現(xiàn)百萬級賬號快速查詢
- 支持IIdentity接口
角色 Role
角色數(shù)據(jù)模型:
<Table Name="Role" Description="角色" RenderGenEntity="true"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Name" DataType="String" Master="True" Nullable="False" Description="名稱" /> <Column Name="Enable" DataType="Boolean" Description="啟用" /> <Column Name="IsSystem" DataType="Boolean" Description="系統(tǒng)。用于業(yè)務系統(tǒng)開發(fā)使用,不受數(shù)據(jù)權(quán)限約束,禁止修改名稱或刪除" /> <Column Name="Permission" DataType="String" Length="500" Description="權(quán)限。對不同資源的權(quán)限,逗號分隔,每個資源的權(quán)限子項豎線分隔" /> <Column Name="Ex1" DataType="Int32" Description="擴展1" /> <Column Name="Ex2" DataType="Int32" Description="擴展2" /> <Column Name="Ex3" DataType="Double" Description="擴展3" /> <Column Name="Ex4" DataType="String" Description="擴展4" /> <Column Name="Ex5" DataType="String" Description="擴展5" /> <Column Name="Ex6" DataType="String" Description="擴展6" /> <Column Name="CreateUser" DataType="String" Description="創(chuàng)建用戶" /> <Column Name="CreateUserID" DataType="Int32" Description="創(chuàng)建用戶" /> <Column Name="CreateIP" DataType="String" Description="創(chuàng)建地址" /> <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創(chuàng)建時間" /> <Column Name="UpdateUser" DataType="String" Description="更新用戶" /> <Column Name="UpdateUserID" DataType="Int32" Description="更新用戶" /> <Column Name="UpdateIP" DataType="String" Description="更新地址" /> <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="更新時間" /> <Column Name="Remark" DataType="String" Length="200" Description="備注" /> </Columns> <Indexes> <Index Columns="Name" Unique="True" /> </Indexes> </Table>
角色表比較簡單主要是名稱和啟用,以及保存菜單權(quán)限數(shù)據(jù)的Permission
角色支持的操作權(quán)限:
/// <summary>操作權(quán)限</summary> [Flags] [Description("操作權(quán)限")] public enum PermissionFlags { /// <summary>無權(quán)限</summary> [Description("無權(quán)限")] None = 0, /// <summary>查看權(quán)限</summary> [Description("查看")] Detail = 1, /// <summary>添加權(quán)限</summary> [Description("添加")] Insert = 2, /// <summary>修改權(quán)限</summary> [Description("修改")] Update = 4, /// <summary>刪除權(quán)限</summary> [Description("刪除")] Delete = 8, /// <summary>所有權(quán)限</summary> [Description("所有")] All = 0xFF, }
主要功能點:
- 數(shù)據(jù)表為空時初始化4個基本角色:管理員、高級用戶、普通用戶、游客
- 啟動時角色權(quán)限校驗,清理角色中無效的權(quán)限項(可能菜單已刪除),以及授權(quán)管理員訪問所有角色都無權(quán)訪問的新菜單
- 支持編號查詢FindByID和名稱查詢FindByID,采用實體緩存,目標系統(tǒng)不會超過1000個角色
- 支持權(quán)限判斷與設置 Has/Get/Set/Reset 等
- 重載實體類 Delete/Save/Update/OnLoad/OnPropertyChanged,加載實體對象時展開權(quán)限,保存時合并
菜單 Menu
菜單數(shù)據(jù)模型:
<Table Name="Menu" Description="菜單" BaseType="EntityTree" RenderGenEntity="true"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Name" DataType="String" Master="True" Nullable="False" Description="名稱" /> <Column Name="DisplayName" DataType="String" Description="顯示名" /> <Column Name="FullName" DataType="String" Length="200" Description="全名" /> <Column Name="ParentID" DataType="Int32" Description="父編號" /> <Column Name="Url" DataType="String" Length="200" Description="鏈接" /> <Column Name="Sort" DataType="Int32" Description="排序" /> <Column Name="Icon" DataType="String" Description="圖標" /> <Column Name="Visible" DataType="Boolean" Description="可見" /> <Column Name="Necessary" DataType="Boolean" Description="必要。必要的菜單,必須至少有角色擁有這些權(quán)限,如果沒有則自動授權(quán)給系統(tǒng)角色" /> <Column Name="Permission" DataType="String" Length="200" Description="權(quán)限子項。逗號分隔,每個權(quán)限子項名值豎線分隔" /> <Column Name="Ex1" DataType="Int32" Description="擴展1" /> <Column Name="Ex2" DataType="Int32" Description="擴展2" /> <Column Name="Ex3" DataType="Double" Description="擴展3" /> <Column Name="Ex4" DataType="String" Description="擴展4" /> <Column Name="Ex5" DataType="String" Description="擴展5" /> <Column Name="Ex6" DataType="String" Description="擴展6" /> <Column Name="CreateUser" DataType="String" Description="創(chuàng)建用戶" /> <Column Name="CreateUserID" DataType="Int32" Description="創(chuàng)建用戶" /> <Column Name="CreateIP" DataType="String" Description="創(chuàng)建地址" /> <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創(chuàng)建時間" /> <Column Name="UpdateUser" DataType="String" Description="更新用戶" /> <Column Name="UpdateUserID" DataType="Int32" Description="更新用戶" /> <Column Name="UpdateIP" DataType="String" Description="更新地址" /> <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="更新時間" /> <Column Name="Remark" DataType="String" Length="200" Description="備注" /> </Columns> <Indexes> <Index Columns="Name" /> <Index Columns="ParentID,Name" Unique="True" /> </Indexes> </Table>
菜單實體類采用樹形實體基類 EntityTree ,通過 ParentID 實現(xiàn)上下級關(guān)聯(lián),同級 ParentID+Name 唯一
主要功能點:
- 支持自動掃描Controller作為菜單,因此魔方只需要增加Controller,即可在菜單表看到新頁面
- 實體樹適用于1000行以內(nèi)樹形數(shù)據(jù)表,一次性加載數(shù)據(jù)到內(nèi)存,在內(nèi)存中根據(jù)ParentID構(gòu)造實體對象樹,最常用樹形是Parent/Childs
日志統(tǒng)計
日志 Log
數(shù)據(jù)模型:
<Table Name="Log" Description="日志" ConnName="Log" RenderGenEntity="true"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Category" DataType="String" Description="類別" /> <Column Name="Action" DataType="String" Description="操作" /> <Column Name="LinkID" DataType="Int32" Description="鏈接" /> <Column Name="UserName" DataType="String" Description="用戶名" /> <Column Name="Ex1" DataType="Int32" Description="擴展1" /> <Column Name="Ex2" DataType="Int32" Description="擴展2" /> <Column Name="Ex3" DataType="Double" Description="擴展3" /> <Column Name="Ex4" DataType="String" Description="擴展4" /> <Column Name="Ex5" DataType="String" Description="擴展5" /> <Column Name="Ex6" DataType="String" Description="擴展6" /> <Column Name="CreateUser" DataType="String" Description="創(chuàng)建用戶" /> <Column Name="CreateUserID" DataType="Int32" Description="用戶編號" /> <Column Name="CreateIP" DataType="String" Description="IP地址" /> <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="時間" /> <Column Name="Remark" DataType="String" Length="500" Description="詳細信息" /> </Columns> <Indexes> <Index Columns="Category" /> <Index Columns="CreateUserID" /> <Index Columns="CreateTime" /> </Indexes> </Table>
日志表記錄分類、操作和日志內(nèi)容。
主要功能點:
- 日志提供者LogProvider,提供了唯一核心方法 WriteLog,默認實現(xiàn)就是寫該日志表。可從對象容器取得日志提供者 ObjectContainer.Resolve<LogProvider>()
- 從IManageProvider接口獲取當前登錄用戶以及遠程訪問IP寫入日志相應字段
在線 UserOnline
數(shù)據(jù)模型:
<Table Name="UserOnline" Description="用戶在線" ConnName="Log"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="UserID" DataType="Int32" Description="用戶" /> <Column Name="Name" DataType="String" Master="True" Description="名稱" /> <Column Name="SessionID" DataType="String" Description="會話。Web的SessionID或Server的會話編號" /> <Column Name="Times" DataType="Int32" Description="次數(shù)" /> <Column Name="Page" DataType="String" Description="頁面" /> <Column Name="Status" DataType="String" Length="200" Description="狀態(tài)" /> <Column Name="OnlineTime" DataType="Int32" Description="在線時間。本次在線總時間,秒" /> <Column Name="CreateIP" DataType="String" Description="創(chuàng)建地址" /> <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創(chuàng)建時間" /> <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="修改時間" /> </Columns> <Indexes> <Index Columns="UserID" /> <Index Columns="SessionID" /> <Index Columns="CreateTime" /> </Indexes> </Table>
借助用戶行為模塊 UserBehaviorModule , 維護用戶在線記錄,持久化在 UserOnline 表
訪問統(tǒng)計 VisitStat
<Table Name="VisitStat" Description="訪問統(tǒng)計" ConnName="Log"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Level" DataType="Int32" Description="層級" Type="XCode.Statistics.StatLevels" /> <Column Name="Time" DataType="DateTime" Description="時間" /> <Column Name="Page" DataType="String" Nullable="False" Description="頁面" /> <Column Name="Title" DataType="String" Master="True" Description="標題" /> <Column Name="Times" DataType="Int32" Description="次數(shù)" /> <Column Name="Users" DataType="Int32" Description="用戶" /> <Column Name="IPs" DataType="Int32" Description="IP" /> <Column Name="Error" DataType="Int32" Description="錯誤" /> <Column Name="Cost" DataType="Int32" Description="耗時。毫秒" /> <Column Name="MaxCost" DataType="Int32" Description="最大耗時。毫秒" /> <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創(chuàng)建時間" /> <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="更新時間" /> <Column Name="Remark" DataType="String" Length="5000" Description="詳細信息" /> </Columns> <Indexes> <Index Columns="Page,Level,Time" Unique="True" /> <Index Columns="Level,Time" /> </Indexes> </Table>
借助用戶行為模塊 UserBehaviorModule , 維護用戶訪問記錄,寫入日志表,并寫入訪問統(tǒng)計表。
主要功能要點:
- 記錄頁面訪問統(tǒng)計,簡單支持IP數(shù)和用戶數(shù)
- 支持年月日三級統(tǒng)計,作為XCode日期統(tǒng)計表的標準示例
其它
部門 Department
數(shù)據(jù)模型:
<Table Name="Department" Description="部門。組織機構(gòu),多級樹狀結(jié)構(gòu)" BaseType="EntityTree" RenderGenEntity="true"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Code" DataType="String" Description="代碼" /> <Column Name="Name" DataType="String" Master="True" Nullable="False" Description="名稱" /> <Column Name="FullName" DataType="String" Length="200" Description="全名" /> <Column Name="ParentID" DataType="Int32" Description="父級" /> <Column Name="Level" DataType="Int32" Description="層級。樹狀結(jié)構(gòu)的層級" /> <Column Name="Sort" DataType="Int32" Description="排序。同級內(nèi)排序" /> <Column Name="Enable" DataType="Boolean" Description="啟用" /> <Column Name="Visible" DataType="Boolean" Description="可見" /> <Column Name="Ex1" DataType="Int32" Description="擴展1" /> <Column Name="Ex2" DataType="Int32" Description="擴展2" /> <Column Name="Ex3" DataType="Double" Description="擴展3" /> <Column Name="Ex4" DataType="String" Description="擴展4" /> <Column Name="Ex5" DataType="String" Description="擴展5" /> <Column Name="Ex6" DataType="String" Description="擴展6" /> <Column Name="CreateUser" DataType="String" Description="創(chuàng)建用戶" /> <Column Name="CreateUserID" DataType="Int32" Description="創(chuàng)建用戶" /> <Column Name="CreateIP" DataType="String" Description="創(chuàng)建地址" /> <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創(chuàng)建時間" /> <Column Name="UpdateUser" DataType="String" Description="更新用戶" /> <Column Name="UpdateUserID" DataType="Int32" Description="更新用戶" /> <Column Name="UpdateIP" DataType="String" Description="更新地址" /> <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="更新時間" /> <Column Name="Remark" DataType="String" Length="200" Description="備注" /> </Columns> <Indexes> <Index Columns="Name" /> <Index Columns="ParentID,Name" Unique="True" /> <Index Columns="Code" /> <Index Columns="UpdateTime" /> </Indexes> </Table>
字典參數(shù) Parameter
數(shù)據(jù)模型:
<Table Name="Parameter" Description="字典參數(shù)"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Category" DataType="String" Description="類別" /> <Column Name="Name" DataType="String" Master="True" Description="名稱" /> <Column Name="Value" DataType="String" Length="200" Description="數(shù)值" /> <Column Name="LongValue" DataType="String" Length="2000" Description="長數(shù)值" /> <Column Name="Kind" DataType="Int32" Description="種類。0普通,21列表,22名值" Type="XCode.Membership.ParameterKinds" /> <Column Name="Enable" DataType="Boolean" Description="啟用" /> <Column Name="Ex1" DataType="Int32" Description="擴展1" /> <Column Name="Ex2" DataType="Int32" Description="擴展2" /> <Column Name="Ex3" DataType="Double" Description="擴展3" /> <Column Name="Ex4" DataType="String" Description="擴展4" /> <Column Name="Ex5" DataType="String" Description="擴展5" /> <Column Name="Ex6" DataType="String" Description="擴展6" /> <Column Name="CreateUser" DataType="String" Description="創(chuàng)建用戶" /> <Column Name="CreateUserID" DataType="Int32" Description="創(chuàng)建用戶" /> <Column Name="CreateIP" DataType="String" Description="創(chuàng)建地址" /> <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創(chuàng)建時間" /> <Column Name="UpdateUser" DataType="String" Description="更新用戶" /> <Column Name="UpdateUserID" DataType="Int32" Description="更新用戶" /> <Column Name="UpdateIP" DataType="String" Description="更新地址" /> <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="更新時間" /> <Column Name="Remark" DataType="String" Length="200" Description="備注" /> </Columns> <Indexes> <Index Columns="Category,Name" Unique="True" /> <Index Columns="Name" /> <Index Columns="UpdateTime" /> </Indexes> </Table>
系列教程
NewLife.XCode教程系列[2019版]
- 增刪改查入門。快速展現(xiàn)用法,代碼配置連接字符串
- 數(shù)據(jù)模型文件。建立表格字段和索引,名字以及數(shù)據(jù)類型規(guī)范,推薦字段(時間,用戶,IP)
- 實體類詳解。數(shù)據(jù)類業(yè)務類,泛型基類,接口
- 功能設置。連接字符串,調(diào)試開關(guān),SQL日志,慢日志,參數(shù)化,執(zhí)行超時。代碼與配置文件設置,連接字符串局部設置
- 反向工程。自動建立數(shù)據(jù)庫數(shù)據(jù)表
- 數(shù)據(jù)初始化。InitData寫入初始化數(shù)據(jù)
- 高級增刪改。重載攔截,自增字段,Valid驗證,實體模型(時間,用戶,IP)
- 臟數(shù)據(jù)。如何產(chǎn)生,怎么利用
- 增量累加。高并發(fā)統(tǒng)計
- 事務處理。單表和多表,不同連接,多種寫法
- 擴展屬性。多表關(guān)聯(lián),Map映射
- 高級查詢。復雜條件,分頁,自定義擴展FieldItem,查總記錄數(shù),查匯總統(tǒng)計
- 數(shù)據(jù)層緩存。Sql緩存,更新機制
- 實體緩存。全表整理緩存,更新機制
- 對象緩存。字典緩存,適用用戶等數(shù)據(jù)較多場景。
- 百億級性能。字段精煉,索引完備,合理查詢,充分利用緩存
- 實體工廠。元數(shù)據(jù),通用處理程序
- 角色權(quán)限。Membership
- 導入導出。Xml,Json,二進制,網(wǎng)絡或文件
- 分表分庫。常見拆分邏輯
- 高級統(tǒng)計。聚合統(tǒng)計,分組統(tǒng)計
- 批量寫入。批量插入,批量Upsert,異步保存
- 實體隊列。寫入級緩存,提升性能。
- 備份同步。備份數(shù)據(jù),恢復數(shù)據(jù),同步數(shù)據(jù)
- 數(shù)據(jù)服務。提供RPC接口服務,遠程執(zhí)行查詢,例如SQLite網(wǎng)絡版
- 大數(shù)據(jù)分析。ETL抽取,調(diào)度計算處理,結(jié)果持久化

浙公網(wǎng)安備 33010602011771號