zoukankan      html  css  js  c++  java
  • 企业应用:浅谈 “数据权限” 和 查询 API 设计

    背景

    多数企业应用都需要对数据权限进行控制,如:某个用户只能看到某个范围的数据(数据行)、某个用户只能看到某几列数据(数据列)。本文以数据行级别的权限控制为范例,谈谈如何设计权限模型和查询 API。

    权限模型

    结合自己的项目需求,可以省略掉“数据角色”,直接让“用户”聚合“数据权限”,也可以只保留一个“角色”,让“角色”聚合“操作权限”和“数据权限”。

    可扩展的数据权限模型

    伪代码示例

     1     class SessionInfo
     2     {
     3         public Guid UserId { get; set; }
     4 
     5         public Guid DepartmentId { get; set; }
     6     }
     7 
     8     interface IDataPermissionProvider
     9     {
    10         string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args);
    11     }
    12 
    13     [DisplayName("我的")]
    14     class DepartmentDataPermissionProvider : IDataPermissionProvider
    15     {
    16         public string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args)
    17         {
    18             return String.Format("( CreateUserId = '{0}' )", sessionInfo.UserId);
    19         }
    20     }
    21 
    22     [DisplayName("指定部门")]
    23     class MySelfDataPermissionProvider : IDataPermissionProvider
    24     {
    25         public string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args)
    26         {
    27             return String.Format("( DepartmentId = '{0}' )", args["DepartmentId"]);
    28         }
    29     }

    草图示例

    说明

    很容易将这部分“插件化”,如支持“自定义”,然后显示一个输入框,可以输入:“Price > 130”。

    如何设计查询API?

    先看两个用例

    上面两个用例,对订单有两种查询需求,我们如何设计这种查询 API 呢?

    1. 第一种:
      1     class QueryService
      2     {
      3         public QueryResult Query(UserCase userCase, DynamicQuery query)
      4         {
      5             // 根据 userCase 决定是否或如何动态的追加数据权限。
      6             return null;
      7         }
      8     }

      需要根据不同的 UserCase,决定是否追加数据权限,如:A 用例需要数据权限,B 用例不需要,UserCase 可能是“当前请求的模块名字”或“当前请求的URL”。

    2. 第二种:
          class QueryService
          {
              public QueryResult QueryA(DynamicQuery query)
              {
                  return null;
              }
      
              public QueryResult QueryB(DynamicQuery query)
              {
                  return null;
              }
          }

      我更喜欢这种风格。

    上面的 DynamicQuery 并不是“万能的查询条件”,而是满足某一用例的不同查询组合的一种“规约”,很多系统都提供“万能查询”,也算是一种特殊的“规约”了。

    另外需要注意的是:一个用例会有多种查询需求的(或者叫查询组合)。

    备注

    仓促成文,有这方面经验的朋友请留言批评。

  • 相关阅读:
    GPS坐标转百度地图并且加载地图示例.支持微信端访问
    关于vs2013 mysql Ef框架中提示版本不兼容问题的解决办法
    CSS3 关于@font-face引用中文字体解决办法
    登录权限,菜单动态加载,动态渲染功能按钮
    vue-router使用next()跳转到指定路径时会无限循环
    三张图较为好理解JavaScript的原型对象与原型链
    深入javascript之原型和原型链
    vue2.0引入现有css文件
    定制简单的404和403页面
    弹框内画echarts图dom元素无法获取的问题
  • 原文地址:https://www.cnblogs.com/happyframework/p/3374442.html
Copyright © 2011-2022 走看看