之前一直在找Vue有没有权限的合集。
于是找到了这个,大概看了下。他似乎提供了一套权限方案。
1 | can(Action.Update, Article, { authorId: user.id }); |
这个是定义一个规则,规则的前提是你需要定义好实体
1 | export class Article { |
然后开始定义规则前的准备
1 | // 定义应用中的主体 |
这个时候就是刚开始的 can
can(Action.Update, Article, { authorId: user.id });
更新 Article 这个对象需要做这 ID 和 User.id 一致, 这个就是规则。
另一个问题就来了,如何调用这个规则?
需要实例化
1 | createForUser(user: User) { |
这是一个实例化的过程,他会返回一个 AppAbility 对象。那么这个对象可以开始检查权限
这个时候就可以开始搞了。
比如,我有一个 router
1 | (":id") |
大概的过程就是这样,很麻烦对吧。
到前端
1 | const ability = this.caslAbilityFactory.createForUser(user); |
通过这样会直接返回前端一个JSON对象,前端引入。
前端通过自己的规则,然后也能实现
1 | ability.can("update", article) |
类似的操作.
首先就是前后端统一。
前端用什么后端就用什么这个确实香。
另外他可以和其他数据库联动,直接查询可以省一些事情
1 | import { accessibleBy } from '@casl/prisma'; |
我可以直接把权限直接放在查询里面.
虽然其实如果你自己来也不是很麻烦,毕竟我也没有那么复杂的逻辑..
casl 本质上是一种权限引擎。
比如现在后台权限系统,一个树形的权限 => 基于菜单来做管理,基于文字类似于 User:view 其实很类似
只是他给你做了一部分功能
并且他可以进行灵活的配置,甚至可以管理到具体资源的级别。
如果做一个大型的管理系统还是不错的.
小型的,你根据角色权限直接写死也是不错的。
比如我有一个权限表 permissions
id: 42
action: “update”
subject: “Article”
inverted: false
conditions: {“authorId”:”${user.id}”}
这是后端的权限表,比如说如果直接写死应该是这样的
1 | cannot('delete', 'Article', { isPublished: true }); |
那么我们去实例化
1 | const { can, cannot, build } = new AbilityBuilder<AppAbility>(Ability as AbilityClass<AppAbility>); |
看规则就有了,剩下的就是需要做一些其他的铺垫,怎么传给前端,怎么生成。
因为他是写json的,有一套自己的规则,比如:{"authorId":"${user.id}"} 。
他就是其他的 “user:view” 之类的纯粹的是和否这种机制相比,就强大很多,可以给很多权限。
1 | { "authorId": "${user.id}" } |
这个是最简单的,仅自己可见对吧?
1 | { "action": "update", "subject": "Article", "fields": ["title", "summary"], "conditions": { "authorId": "${user.id}" } } |
我甚至可以通过字段进行全权限控制
1 | { "$or": [ { "isPublic": true }, { "sharedWith": { "$in": ["${user.id}"] } } ] } |
多条件
1 | { "tags": { "$all": ["tech", "ai"] } } |
数组匹配
1 | { "inverted": true, "action": "delete", "subject": "Article", "conditions": { "isLocked": true } } |
他还可以玩优先级覆盖
等等等等等,他可以动态管理复杂的资源。各种动态权限。
剩下的就要看文档了,目前还没有开始做项目。
有机会我已经要试试。