本文目的
权限控制,只要不是单机应用,几乎都会用到。前一整子为一个新项目添加了权限控制,采用的是基于角色的方式,感觉实现起来比较简单,而且实用,所以记录下来,作为备忘,以后应该用得着。
权限=行为+数据类型
在此解决方案中,权限是行为与数据类型的组合。
- 行为:对数据的增,删,该,查就是最基本的行为。当然还有其他的行为,比如启用或禁用某功能。
- 数据类型:不同的应用具有不同的数据类型。比如电商网站,那么商品,类目,买家,卖家等都是数据类型。
通过短码对行为和数据唯一标识,通过行为和数据的组合标识权限。举个例子,对于增删该查,可以分别用“add”,“delete”,“edit”,“read”这个几个单词的前几个字母标识,依次是“add”,“de”,“ed”,“re”。对于商品(product),类目(category),卖家(seller),买家(customer),也可以分别用“pr”,“ca”,“se”,“cu”标识。
现在用上面的短码来确应一个权限,如“查看卖家信息”权限,可以使用“re:cu”来标识。
用户-角色-权限
角色是权限的集合。角色是作为用户与权限的纽带,可以方便的设置用户具的权限。下面是角色,权限和用户三者之间的关系。
上面表中的id,name和description都是一些常用字段,主要需要注意permission表中的actionCode字段和dataTypeCode字段,这些是用来存放行为和数据类型简码。通过上面的表关系,可以定位用户具有哪些权限。同时,为用户添加删除角色也十分方便。
访问控制
此方按试用于PHP项目,但不仅限于PHP。在任何页面的开始部分使用如下代码:
=============================================
assertAccessHtml(actionCode, dataTypeCode)
或
assertAccessJson(actionCode, dataTypeCode)
==============================================
上面两个函数执行的逻辑相同,只是在用户没有权限时,输出不同。前者直接输出错误页面,后者输出相同内容的json数据,适用于异步访问。上面两个函数的逻辑如下:
- 在session中拿到当前用户的id
- 获取用户的所有权限(可以直接访问DB,也可以通过缓存)
- 根据传入的actionCode和dataTypeCode的组合,检测用户是否具有权限
- 如果有,怎么都不做,直接返回
- 如果没有权限,提示错误,并退出当前请求
结语
此方案的不足在于权限控制的粒度不能到数据级别。但是,并不是每一个功能都需要将权限控制限制在数据级别。对特定模块,可以做特殊处理。没有最好的权限控制方案,只有最适合项目的权限控制方案,希望此方案对你有用。