[NewLife.XCode]角色權限

NewLife.XCode是一個有10多年歷史的開源數據中間件,支持nfx/netcore,由新生命團隊(2002~2019)開發完成並維護至今,以下簡稱XCode。

整個系列教程會大量結合示例代碼和運行日誌來進行深入分析,蘊含多年開發經驗於其中,代表作有百億級大數據實時計算項目。

開源地址:https://github.com/NewLifeX/X (求star, 864+)

 

前面講解了XCode的各種用法,這一章我們來講講內置的Membership,同時也是XCode的第一標準示例!

 

設計背景

現代管理信息系統絕大部分採用BS架構,無一例外需要用戶角色權限的支持!

結合團隊諸多兄弟姐妹的經驗,設計了一個大小適中的用戶權限系統Membership,目標是滿足80%的使用場景,並具備一定的擴展性。

 

Membership剛開始就採用了角色授權體系,每個用戶只有一種角色,角色擁有菜單資源權限集。

隨着Membership實用性日益增加,2015年初正式合併進入XCode,作為一個模塊存在。

 

2016年第二代魔方NewLife.Cube採用ASP.Net MVC5重構,讓Membership的榮譽達到了鼎峰!

在MVC中,每個Controller就是一個菜單資源,其下的Search/Detail/Insert/Update/Delete等Action作為角色在該菜單資源下的權限子項,保存在角色屬性數據中。

 

2018年為了增強魔方功能,在某些場景下支持單用戶多角色,且兼容已有系統,用戶表增加RoleIDs字段,保存擴展角色,原來的RoleID作為主角色。

 

管理提供者

管理提供者接口 IManageProvider ,提供了Membership基本操作實現。

  1. 當前登錄用戶 GetCurrent、SetCurrent,靜態訪問 ManageProvider.User
  2. 查找用戶 FindByID、FindByName
  3. 註冊登錄註銷 Register、Login、Logout
  4. 當前用戶主機(訪問者IP)ManageProvider.UserHost
  5. IManageProvider 默認由XCode.Membership中的UserX/Role/Menu支持,如若用戶使用自己的用戶權限表,可重新實現該接口

 

用戶權限

用戶 UserX

用戶數據模型:

  <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="部門。組織機構" />
      <Column Name="Online" DataType="Boolean" Description="在線" />
      <Column Name="Enable" DataType="Boolean" Description="啟用" />
      <Column Name="Logins" DataType="Int32" Description="登錄次數" />
      <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、用戶名和密碼,登錄註冊相關信息;

角色RoleID、RoleIDs用於實現權限集控制;

部分場景需要郵箱Mail、手機Mobile或者工號Code登錄;

如果仍然不能滿足要求,可以考慮使用Ex1~Ex6等擴展字段。

 

常用功能點:

  1. 初始化時,如果數據表為空,自動插入admin/admin用戶賬號,角色是“管理員”
  2. 支持註冊登錄,使用MD5保存密碼
  3. 支持編號查詢FindByID和名稱查詢FindByName,分別採用了對象緩存和對象從鍵,輕鬆實現百萬級賬號快速查詢
  4. 支持IIdentity接口

 

角色 Role

角色數據模型:

  <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="系統。用於業務系統開發使用,不受數據權限約束,禁止修改名稱或刪除" />
      <Column Name="Permission" DataType="String" Length="500" 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="創建用戶" />
      <Column Name="CreateUserID" DataType="Int32" Description="創建用戶" />
      <Column Name="CreateIP" DataType="String" Description="創建地址" />
      <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創建時間" />
      <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>

角色表比較簡單主要是名稱和啟用,以及保存菜單權限數據的Permission

角色支持的操作權限:

    /// <summary>操作權限</summary>
    [Flags]
    [Description("操作權限")]
    public enum PermissionFlags
    {
        /// <summary>無權限</summary>
        [Description("無權限")]
        None = 0,

        /// <summary>查看權限</summary>
        [Description("查看")]
        Detail = 1,

        /// <summary>添加權限</summary>
        [Description("添加")]
        Insert = 2,

        /// <summary>修改權限</summary>
        [Description("修改")]
        Update = 4,

        /// <summary>刪除權限</summary>
        [Description("刪除")]
        Delete = 8,

        /// <summary>所有權限</summary>
        [Description("所有")]
        All = 0xFF,
    }

主要功能點:

  1. 數據表為空時初始化4個基本角色:管理員、高級用戶、普通用戶、遊客
  2. 啟動時角色權限校驗,清理角色中無效的權限項(可能菜單已刪除),以及授權管理員訪問所有角色都無權訪問的新菜單
  3. 支持編號查詢FindByID和名稱查詢FindByID,採用實體緩存,目標系統不會超過1000個角色
  4. 支持權限判斷與設置 Has/Get/Set/Reset 等
  5. 重載實體類 Delete/Save/Update/OnLoad/OnPropertyChanged,加載實體對象時展開權限,保存時合併

 

菜單 Menu

菜單數據模型:

  <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="必要。必要的菜單,必須至少有角色擁有這些權限,如果沒有則自動授權給系統角色" />
      <Column Name="Permission" DataType="String" Length="200" 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="創建用戶" />
      <Column Name="CreateUserID" DataType="Int32" Description="創建用戶" />
      <Column Name="CreateIP" DataType="String" Description="創建地址" />
      <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創建時間" />
      <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 實現上下級關聯,同級 ParentID+Name 唯一

 

主要功能點:

  1. 支持自動掃描Controller作為菜單,因此魔方只需要增加Controller,即可在菜單表看到新頁面
  2. 實體樹適用於1000行以內樹形數據表,一次性加載數據到內存,在內存中根據ParentID構造實體對象樹,最常用樹形是Parent/Childs

 

日誌統計

日誌 Log

數據模型:

  <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="創建用戶" />
      <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>

日誌表記錄分類、操作和日誌內容。

主要功能點:

  1. 日誌提供者LogProvider,提供了唯一核心方法 WriteLog,默認實現就是寫該日誌表。可從對象容器取得日誌提供者 ObjectContainer.Resolve<LogProvider>()
  2. 從IManageProvider接口獲取當前登錄用戶以及遠程訪問IP寫入日誌相應字段

 

在線 UserOnline

數據模型:

  <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="次數" />
      <Column Name="Page" DataType="String" Description="頁面" />
      <Column Name="Status" DataType="String" Length="200" Description="狀態" />
      <Column Name="OnlineTime" DataType="Int32" Description="在線時間。本次在線總時間,秒" />
      <Column Name="CreateIP" DataType="String" Description="創建地址" />
      <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創建時間" />
      <Column Name="UpdateTime" DataType="DateTime" Nullable="False" Description="修改時間" />
    </Columns>
    <Indexes>
      <Index Columns="UserID" />
      <Index Columns="SessionID" />
      <Index Columns="CreateTime" />
    </Indexes>
  </Table>

藉助用戶行為模塊 UserBehaviorModule , 維護用戶在線記錄,持久化在 UserOnline 表

 

訪問統計 VisitStat

  <Table Name="VisitStat" Description="訪問統計" 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="次數" />
      <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="創建時間" />
      <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 , 維護用戶訪問記錄,寫入日誌表,並寫入訪問統計表。

主要功能要點:

  1. 記錄頁面訪問統計,簡單支持IP數和用戶數
  2. 支持年月日三級統計,作為XCode日期統計表的標準示例

 

其它

部門 Department

數據模型:

  <Table Name="Department" Description="部門。組織機構,多級樹狀結構" 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="層級。樹狀結構的層級" />
      <Column Name="Sort" DataType="Int32" Description="排序。同級內排序" />
      <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="創建用戶" />
      <Column Name="CreateUserID" DataType="Int32" Description="創建用戶" />
      <Column Name="CreateIP" DataType="String" Description="創建地址" />
      <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創建時間" />
      <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>

 

 

字典參數 Parameter

數據模型:

  <Table Name="Parameter" Description="字典參數">
    <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="數值" />
      <Column Name="LongValue" DataType="String" Length="2000" Description="長數值" />
      <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="創建用戶" />
      <Column Name="CreateUserID" DataType="Int32" Description="創建用戶" />
      <Column Name="CreateIP" DataType="String" Description="創建地址" />
      <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="創建時間" />
      <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版]

  1. 增刪改查入門。快速展現用法,代碼配置連接字符串
  2. 數據模型文件。建立表格字段和索引,名字以及數據類型規範,推薦字段(時間,用戶,IP)
  3. 實體類詳解。數據類業務類,泛型基類,接口
  4. 功能設置。連接字符串,調試開關,SQL日誌,慢日誌,參數化,執行超時。代碼與配置文件設置,連接字符串局部設置
  5. 反向工程。自動建立數據庫數據表
  6. 數據初始化。InitData寫入初始化數據
  7. 高級增刪改。重載攔截,自增字段,Valid驗證,實體模型(時間,用戶,IP)
  8. 臟數據。如何產生,怎麼利用
  9. 增量累加。高併發統計
  10. 事務處理。單表和多表,不同連接,多種寫法
  11. 擴展屬性。多表關聯,Map映射
  12. 高級查詢。複雜條件,分頁,自定義擴展FieldItem,查總記錄數,查匯總統計
  13. 數據層緩存。Sql緩存,更新機制
  14. 實體緩存。全表整理緩存,更新機制
  15. 對象緩存。字典緩存,適用用戶等數據較多場景。
  16. 百億級性能。字段精鍊,索引完備,合理查詢,充分利用緩存
  17. 實體工廠。元數據,通用處理程序
  18. 角色權限。Membership
  19. 導入導出。Xml,Json,二進制,網絡或文件
  20. 分表分庫。常見拆分邏輯
  21. 高級統計。聚合統計,分組統計
  22. 批量寫入。批量插入,批量Upsert,異步保存
  23. 實體隊列。寫入級緩存,提升性能。
  24. 備份同步。備份數據,恢複數據,同步數據
  25. 數據服務。提供RPC接口服務,遠程執行查詢,例如SQLite網絡版
  26. 大數據分析。ETL抽取,調度計算處理,結果持久化

【精選推薦文章】

自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

您可能也會喜歡…