背景

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

权限模型

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

可扩展的数据权限模型

伪代码示例

     class SessionInfo
{
public Guid UserId { get; set; } public Guid DepartmentId { get; set; }
} interface IDataPermissionProvider
{
string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args);
} [DisplayName("我的")]
class DepartmentDataPermissionProvider : IDataPermissionProvider
{
public string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args)
{
return String.Format("( CreateUserId = '{0}' )", sessionInfo.UserId);
}
} [DisplayName("指定部门")]
class MySelfDataPermissionProvider : IDataPermissionProvider
{
public string CreateSQL(SessionInfo sessionInfo, Dictionary<string, object> args)
{
return String.Format("( DepartmentId = '{0}' )", args["DepartmentId"]);
}
}

草图示例

说明

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

如何设计查询API?

先看两个用例

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

  1. 第一种:

         class QueryService
    {
    public QueryResult Query(UserCase userCase, DynamicQuery query)
    {
    // 根据 userCase 决定是否或如何动态的追加数据权限。
    return null;
    }
    }

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

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

    我更喜欢这种风格。

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

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

备注

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

企业应用:浅谈 “数据权限” 和 查询 API 设计的更多相关文章

  1. 【ASP.NET MVC系列】浅谈数据注解和验证

    [ASP.NET MVC系列]浅谈数据注解和验证   [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google C ...

  2. Python Web 基础向(四) 浅谈数据层

    数据层一般会给人带来一些困扰,在于其定位不准确.聚合Model的工作也可以放在逻辑层做,但会导致逻辑层变重,经常出现大段晦涩代码.因此我的建议是保留Model聚合层,尽管会导致工作量的略微增加,但却可 ...

  3. 浅谈iOS中MVVM的架构设计与团队协作

    说到架构设计和团队协作,这个对App的开发还是比较重要的.即使作为一个专业的搬砖者,前提是你这砖搬完放在哪?不只是Code有框架,其他的东西都是有框架的,比如桥梁等等神马的~在这儿就不往外扯了.一个好 ...

  4. IOS中 浅谈iOS中MVVM的架构设计与团队协作

    今天写这篇文章是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇文章的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  5. 浅谈iOS中MVVM的架构设计与团队协作【转载】

    今天写这篇文章是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇文章的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  6. [PHP] 浅谈 Laravel Authentication 的 auth:api

    auth:api 在 Laravel 的 Routing , Middleware , API Authentication 主题中都有出现. 一. 在 Routing 部分可以知道 auth:api ...

  7. 数据层的多租户浅谈(SAAS多租户数据库设计)

    在上一篇“浅析多租户在 Java 平台和某些 PaaS 上的实现”中我们谈到了应用层面的多租户架构,涉及到 PaaS.JVM.OS 等,与之相应的是数据层也有多租户的支持. 数据层的多租户综述 多租户 ...

  8. [转载]数据层的多租户浅谈(SAAS多租户数据库设计)

    原文:http://www.ibm.com/developerworks/cn/java/j-lo-dataMultitenant/index.html 在上一篇“浅析多租户在 Java 平台和某些 ...

  9. 浅谈mysql权限

    一.      背景: “去IOE”的本质是“分布式+开源”架构替代“集中式+封闭”架构,变成彻底的云计算服务模式.去“IE”易,并且应该去,关键确实能省钱,而且运维难度不大,替代技术产品成熟.而去O ...

随机推荐

  1. Mariadb 10.2中的json使用及应用场景思考

    -- 创建示例表DROP TABLE IF EXISTS `t_base_user`;CREATE TABLE `t_base_user`  (  `USER_ID` char(36) CHARACT ...

  2. K8S网络排故障一则--iptables规则

    这个故障源起来在k8s上同时安装ceph群集(测试的时候机器不多啊) 当这两者都OK之后,原来k8s上的服务实例,则有的通,有的不通了. ==================== 所有可能的故障点,f ...

  3. C# HTML 生成 PDF

    原文出处:http://www.cnblogs.com/shanyou/archive/2012/09/07/2676026.html

  4. 牛客网 牛客练习赛43 B.Tachibana Kanade Loves Probability-快速幂加速

    链接:https://ac.nowcoder.com/acm/contest/548/B来源:牛客网 Tachibana Kanade Loves Probability 时间限制:C/C++ 1秒, ...

  5. Java常用工具类之Excel导出

    package com.wazn.learn.util; import java.util.List; import java.util.Map; import org.apache.poi.hssf ...

  6. 【栈模拟dfs】Cells UVALive - 3486

    题目链接:https://cn.vjudge.net/contest/209473#problem/D 题目大意:有一棵树,这棵树的前n个节点拥有子节点,告诉你n的大小,以及这n个节点各有的子节点个数 ...

  7. 创建操作表(UIActionSheet)

    UIActionSheet用来创建一个操作表,它的初始化代码如下: - (IBAction)testActionSheet:(id)sender { UIActionSheet *actionShee ...

  8. 2018ECfinal J. Philosophical Balance

    2018ECfinal J. Philosophical Balance 题目大意: 给出一个字符串 \(s\) ,你需要给每一个 \(i\) 一个 \([0,1]\) 之间的权值 \(k_i\) , ...

  9. 「UOJ218」火车管理

    「UOJ218」火车管理 解题思路:观察发现,在弹出 \(x\) 之前,它前面这个元素都是保持不变的,所以可以用一棵可持久化线段树维护每一个栈顶元素的插入时间,每次找到当前时间\(-1\) 的版本就可 ...

  10. django基础入门

    1. http协议 1.1 请求协议 请求协议格式: 请求首行: // 请求方式 请求路径 协议和版本,例如:GET /index.html HTTP/1.1 请求头信息: // 请求头名称:请求头内 ...