从几个月前开始接触REST,到现在尝试去设计、开发一个RESTful的web应用。说实话,到目前为止我还对REST理解的很浅很浅。今天偶尔又去翻了翻互动百科对REST的描述,感觉那位网友写的真好,但是有些观点我还是有不同的意见。
互动百科上关于REST的页面:
http://www.hudong.com/wiki/REST
1.上面比较后面的一句话里说到:如果我们可以把所有的用户需求都可以抽象为资源,那么MVC就可以退出历史的舞台了。如果情况相反,那么我们就需要混合使用REST和MVC。
我个人看到这句话后,立马觉得不可思议,什么时候MVC和资源杠上了?甚至到达了非彼即此的地步!MVC仅仅是一种分层结构而已,它只是隔离了用户界面和真正的业务逻辑代码,然后靠控制器来连接这两者,在这个分层里,完全没有涉及到资源哇,注意我这里说”涉及“,并不是说MVC中不可能出现资源的概念。所以我很有疑问,假设用户需求(web应用里,用户需求=http请求响应)都能抽象成资源,那么MVC就可以退出历史的舞台了,这句话说的太过了,资源和MVC根本就不是对立的。在REST中,资源被URL标识,用户依靠url来发出请求,请求到达服务器,服务器提供相应的url处理并响应,这个过程你可以设计成MVC模式的,也可以设计成最恶心的页面写代码的模式,例如你完全可以将url直接发到某个jsp上面嘛。然后逻辑代码全都写在页面上。你敢说这不是RESTful的嘛?在MVC Model1的年代里,JSP页面既充当控制器,又充当视图,JavaBean封装业务逻辑,在那个架构中,也完全可以RESTful。所以这两者完全不是非彼即此的关系。
2.REST的核心问题是如何抽象资源。
关于这点我表示很赞成。资源是一个很抽象的东东。极端点的,可以认为任何能够被标识的东东都能被抽象成资源。说到这里,我其实很想谈谈在我前一篇文章里有个朋友问到”分页权限控制“问题,说基于RBAC的权限控制很难、甚至无法对分页适用。详情看
http://www.iteye.com/topic/1112793二楼,当时我也一下子表示不太明白。现在回头想想,其实RBAC的权限控制本身是适合的,关键问题是,他们在解决分页权限这种涉及到数据级别的权限控制问题上,总是想用sql语句来解决它!
我尝试假想一下下面这种场景:
实体:新闻(id,分类,标题,内容,作者)
实体:分类(id,名称)
实体关系:新闻(多)—>分类(一)
REST:
用户需求 url设计
分页查看所有新闻 news/index/{pageNum} GET
分页查看某类新闻 news/{cate}/index/{pageNum} GET
查看某篇新闻 news/{id} GET
查询所有新闻且是分页的 news/search/{keyword}/{pageNum} GET
发表新闻 news POST
删除新闻 news/{id} DELETE
修改新闻 news/{id} PUT
这里我可能比较极端,尽力在避免url含有?后面的参数,因为http的url是?前面部分。既然要用url唯一标识资源,那么肯定不能靠两个相同的url,不同的?参数来标识,因为在http中(至少在tomcat)中,这两者是一样的。除非你自己实现一个判断url+?后面参数来保证url的唯一性,但是http方法中的POST、GET、PUT、DELETE却可以。虽然后两者浏览器不支持,但是http协议包含。
回到前面的场景,上次在我那帖子里,那位朋友说到分页权限控制问题。在这里我利用上面的场景,模拟一下他说的情况,当然不一定理解到他的意思。
现在有一个新的需求:在后台登陆用户中,信息发布员角色的用户只能查看作者为自己的新闻。
问题来了:在我们前面设计的url中,分页查看某类新闻或者分页查看所有新闻中都没有关于新闻作者的权限控制。那么,这时候我们该怎么办?
好多人可能会:在代码里保证(sql语句里),尽力满足新的需求,但是这样问题更多了,这时候权限控制就麻烦了,因为此时很明显的基于url的权限控制模型无效了!因为这时候你不是靠url来控制权限,而是通过sql语句了。
我个人是非常不赞同这种做法的,这种做法很恶心,虽然交给sql语句来做看起来不错。嗯,是的,我并不反对通过sql语句来辅助,但是我反对通过sql语句来控制权限。注意这里我强调的是”sql语句控制权限“。在我的那篇文章里似乎表达的应该是基于url来控制。因为在我看来,确实web应用系统里所有的需求都能被抽象成资源,用url来标识。
关键点出来了,需求——>抽象——>资源<——URL标识。
那么,上面新的需求是:在后台登陆用户中,信息发布员角色的用户只能查看作者为自己的新闻。下面我们的任务将是如何来把这个需求抽象成资源,而不是想法设法的去动其他需求里写好的代码。
我个人会这么做:该新的需求中影响到了它的另外几个需求,把被影响的两个url的权限从信息发布员用户权限中去除。新定义两个url,分配给该用户。具体做法是:
角色为信息发布员的用户:
分页查看所有新闻 news/index/{pageNum} GET 删除该角色用户的访问权限
分页查看某类新闻 news/{cate}/index/{pageNum} GET 同上
查询所有新闻且是分页的 news/search/{keyword}/{pageNum} GET 同上
为该角色新添加符合它需求的url,然后分配权限给该角色。下面仅举一个例子:
分页查看所有作者为当前用户的新闻 news/index/{pageNum}/{author}
在这个url映射到的action处理方法中,该怎么写就怎么写,无需去管权限的问题,也就是说,在action代码中,不要尝试的去比较传过来的author的值和session用户中的值。因为我的url权限控制模型已经帮你做了。至于具体如何做,这里暂时不想谈,但是可以说说原理,1.拦截器(是对每次action访问的拦截,且在拦截器中能够根据当前拦截到的url,找到绑定到它的url参数适配器,例如对于{author}参数的适配器,在该适配器中,大概思路是获取author,然后跟当前session中的用户作者比较,如果不同,就输出权限不够的信息。否则,chain一下就完事了。当然,适配器肯定是支持用户自己扩展的。)
稍微补充点:我的url权限控制模型,url是支持变量的,例如news/index/{pageNum},这个url在真正进入角色权限表时,是会被转成正则表达式news/index/\d+,分配给某角色之后,该角色访问所有news/index/数字都会被通过。另外,该模型还能够在定义url的时候,允许自己实现对url动态参数的赋值。例如news/index/{pageNum}可以给它绑定一个参数适配器,在该适配器中,可以给定值给pageNum,告诉模型,该值只能是什么,例如只能是1,2,3等,甚至可以是是session中的值,总之,该模型本质上是一个拦截器,能够获取reqeust,response,out,session等重要的环境对象。
最后总结下:其实基于RBAC下的url权限控制模型是可靠的,一般而言,需要权限控制的数据都在访问url中能够获取,那么对于数据库字段或者行级别的权限验证,是能够通过url参数适配器的方式去实现的。而且整个url权限控制模型又符合RESTful。
自家之言,欢迎拍砖。PS:暂时还在晚上我的这个url权限控制模型中。但是思路总体来说就是上面所讲。
谢谢阅读。
分享到:
相关推荐
基于REST风格的RBAC模型研究,主要就是针对REST集合的权限管理的开发.
yii2 rbac yii2 rest RBAC Auth manager for-yii2-rest-rbac
RBAC 权限控制 设计文档 演示文稿 基于RBAC的权限控制系统设计演示文稿 以学校教学系统为实例
django基于RBAC模型的权限控制的一整套基础开发平台,前后端分离,后端采用 django+django-rest-framework
RBAC 通用权限设计RBAC 通用权限设计RBAC 通用权限设计RBAC 通用权限设计RBAC 通用权限设计
基于SSH的RBAC权限控制例子,基于SSH的RBAC权限控制例子
CI框架实现用户权限控制,rbac权限控制代码示例,php代码完整压缩包
基于rbac模型的权限管理系统,角色,权限,用户等的权限分配
yii2 rbac yii2 rest RBAC Auth manager for-yii-rest-admin
基于RBAC模型的权限控制的一整套基础开发平台,前后端分离,后端采用django+django-rest-framework,前端采用vue+ElementUI。
基于RBAC模型的权限控制的一整套基础开发平台,前后端分离,前端采用D2Admin 、Vue、ElementUI。后端采用 Python 语言 Django 框架以及强大的 Django REST Framework,权限认证使用Django REST Framework SimpleJWT...
本项目基于Spring,整合Spring的security模块,实现用户管理和权限控制,是一套较为通用的权限控制功能,主要内容如下: 1.登录,包括“记住我”的功能; 2.加密,存储的密码不采用明文,初始密码1234; 3.拦截器...
FastAPI+Vue3,RBAC权限管理,实现 菜单、路由、按钮、接口 权限控制;笔记ht-mini-rbac
项目概述:本源码为基于角色基础访问控制(RBAC)模型的中小型应用开发平台,采用前后端分离架构。后端基于Python的Django框架和Django REST Framework实现,前端则使用Vue.js配合ElementUI进行构建。移动端支持通过...
RBAC用户角色权限,RBAC用户角色权限设计方案
一种基于RBAC 的Web 环境下信息系统权限控制方法.pdf
基于RBAC的通用权限管理构件,采用java语言开发,使用到了SSH技术
简单的RBAC权限管理,包含了监听器、过滤器和拦截器,带有sql文件。
该项目主要展示 RBAC 的权限控制效果,并提供员工管理模块以供测试。用户登录系统后,根据用户所关联的角色,查询角色拥有的权限,如:菜单权限、按钮权限。不同角色的用户,所显示的菜单可能也不尽相同。 系统...
django-vue3-admin 基于RBAC模型的权限控制的一整套基础开发平台,权限粒度达到列级别,前后端分离,后端采用django + django-rest-framework,前端采用基于 vue3 + CompositionAPI + typescript + vite + ele