根据RESTful的相关风格规范, 我们将请求映射为以下几种操作
GET /users/ -----> `list.users`
GET /users/:id/ -----> `retrieve.users`
POST /users/ -----> `create.users`
PUT /users/:id/password/ -----> `replace.users`
PATCH /users/:id/ -----> `update.users`
DELETE /users/:id/ -----> `destroy.users`
如果后端以MVC模式进行开发, 那么我们可以映射如下控制器
`list.users` -----> list(users)
`retrieve.users` -----> retrieve(user,id)
`create.users` -----> create(users)
`replace.users` -----> replace(users,id,field)
`update.users` -----> update(users,id)
`destroy.users` -----> destroy(users,id)
权限的管理采用传统的RBAC模式
1
torbrowserbridge 2017-04-12 10:48:00 +08:00
并没觉得新在哪里。
我们的做法:功能权限前置,数据权限后置(对应你这里资源权限)。 现在想想,设计良好的系统也可以做到数据权限前置,而不会(明显)增加查询次数。比如,将数据权限中的查询结果透传给控制器。 |
2
prasanta OP @torbrowserbridge 数据权限前置我发现的最大问题就是不同类型的资源可能有不同的判断方式,如果针对不同资源写不同方法,前置的意义也就不大了
|
3
torbrowserbridge 2017-04-12 10:56:52 +08:00
@prasanta 对,会丧失一定的灵活性。通常数据权限的判断逻辑非常复杂多样。所以要综合权衡一下利弊。
|
4
prasanta OP @torbrowserbridge 市面上现在似乎没有鉴权规范化的项目
|
5
zhengxiaowai 2017-04-12 11:19:17 +08:00
1. RESTful 标准中 PATCH 的语义是 update/replace , PUT 的语义是 update/modify 。我认为用一个 PUT 方法就可以,没必要多一个 PATCH ,少一接口,多一份放心。很多 API 都没有实现 PATCH 方法,都是用 PUT 实现的。
2. 我觉得放在控制器中比较好。一般来说中间件是一种通用的解决方案,权限控制又是一种十分复杂而且多变的。作为一个中间件,没有任何复用性可言。 |
6
weaming 2017-04-12 11:54:33 +08:00
不是 PUT 添加, POST 修改吗
|
7
scofieldpeng 2017-04-12 12:22:20 +08:00
@weaming 童鞋,你确定你看的不是假文档?
|
8
otakustay 2017-04-12 12:23:36 +08:00
@weaming POST 添加, PUT 修改, PUT 的 URL 指向**唯一**资源
@zhengxiaowai PATCH 可以是 partial entity , PUT 不行,所以这里还是有区别的 |
9
weaming 2017-04-12 12:35:16 +08:00
|
10
ihuotui 2017-04-12 12:53:49 +08:00 via iPhone
其实这样写 性能低,有测试过,在解析 url 时候
|
11
otakustay 2017-04-12 12:59:15 +08:00
@weaming yes ,只要你知道资源的唯一 URL 就无论添加还是修改都行,但如果只知道一个 collection 的 URL 就不行
|
13
ihuotui 2017-04-12 17:01:59 +08:00 via iPhone
@prasanta 就是单单测试 url 性能,{id}get 和 get?id=xx
这两种比较。权限可以在 filter 或者 interseter 里面判断。反正都是 具体功能前的,而且最佳就是加上权限缓存。 |
14
ihuotui 2017-04-12 17:03:29 +08:00 via iPhone
反正我不用 resetful 规范,因为业务多了就不优雅了。
|
15
kenshinhu 2017-04-12 17:03:38 +08:00
话说 PATCH 好像不支持 formdata 吧?有图片上传的操作这个的话就比较麻烦了
|
16
prasanta OP @kenshinhu 文件上传通常是统一做成单独的接口,以 Post 方式上传至 oss 或者其它地方,获取到返回的文件信息后再用于其它接口
|
18
justfly 2017-04-12 17:42:06 +08:00 1
最好设计上保持鉴权逻辑的通用和统一 ,然后鉴权前置。
至于所说的多一次数据库查询问题,可以把鉴权时查询到的数据放到一个当前请求的 context 中,业务逻辑如有需要,可以直接使用这个 context 中的数据,请求结束数据根据 context 一起销毁。 |
19
kenshinhu 2017-04-12 17:59:35 +08:00
@prasanta 这样会不会增加客户端的工作?这样做法 客户端所有涉及文件 的都 得先上转 oss 再把回来的信息 post 到服务器上
之前我也有想过这个方式 ,但好像会增加客户端的工作量,之后就没有这样做了 给写入方法都 是用 POST + formdata 实现 |
20
hantsy 2017-04-12 19:03:32 +08:00
1. 使用用 OAuth/OpenID 或者 JWT 时,返回的 Token 中都可以添加一个 scopes ,在用户登录时取得该用户所有的权限。与服务器交互一般都是 Stateless 方式去请求 API , Header 加上 Token 。
2. 服务器端解密 Token , 可以得到该用户分配的所有权限。直接对照检测 API 权限就行了。 上述方法与所用语言无关。 |
21
wc951 2017-04-12 19:05:54 +08:00 via Android
没觉得新在哪啊, apache shiro 不就在干这事吗,不过那个是 java 的
|
22
hantsy 2017-04-12 19:09:14 +08:00
@zhengxiaowai Patch 已经有相关的具体标准 JSON Patch 等,去修改 Entity 部分属性。
https://tools.ietf.org/html/rfc6902 之前我用到了 Spring Sync 支持 Patch 。 https://spring.io/blog/2014/10/22/introducing-spring-sync 下一代的 JAXRS 2.1 ( Java EE 8 标准)会加入官方的 Patch 支持(虽然自己实现不难)。 |
23
ihuotui 2017-04-12 21:47:53 +08:00
权限
如果你是了解 spring mvc,权限验证可以放在 interceptor http->tomcat->interceptor(check user is login and auth resource)->biz_service restful 风格,感觉它只是给了一个指导,实际需要我们自己拓展. 我建议使用 biz_group/biz_add or other 数据放在 post 中 因为在复杂业务下,需要表达的含义远多于 crud,从可读代码上看 |
24
honmaple 2017-04-13 00:20:46 +08:00
我是觉得作为中间件放到控制器之前好,首先代码侵入性较小,其次只需要单独维护一套权限系统就行,只要简单修改就可以用到其它系统中,权限的验证无非是验证 + 回调,我不认为会增加复杂性,当然,会造成额外的数据查询这是个问题
|