在需要身份验证的前端应用程序中,我们通常希望通过用户角色来决定什么是可见的。例如,访问者可以阅读文章,但注册用户或管理员可以看到编辑按钮。
在前端管理权限可能有点麻烦。您可能以前编写过此代码:
If(用户。type===admin | | user。authpost。所有者===用户。id){ 0.}作为替代方案,简单轻量的库——CASL——可以使管理用户权限变得非常简单。只要用CASL定义权限并设置当前用户,就可以将上面的代码更改为:
If (capabilities.can ('update ',' post '){).}在本文中,我将展示如何使用Vue.js和CASL来管理前端应用程序中的权限。
例如,CASL规则可以指示用户可以对给定的资源和实例(帖子、文章、评论等)执行哪些CRUD(创建、读取、更新和删除)操作。).
假设我们有分类广告网站。最明显的规则是:
访问者可以浏览所有帖子
管理员可以浏览所有帖子并更新或删除它们
对于CASL,我们使用能力构建器来定义规则。调用can来定义新规则。例如:
onst { abilityBuilder }=require(' casl ');导出函数(类型){ abilityBuilder . define(can={ switch(type){ case ' guest ' : can(' read ',' Post ');打破;case 'admin':可以(' read ',' Post ');可以(['更新','删除'],'发布');打破;//在此添加更多角色} } };现在,您可以使用定义的规则来检查应用程序权限。
从“”导入定义的权限。/能力';让currentUser={ id: 999,name : ' Julie ' type : ' registered ',};让能力=defineableilities for(currentuser . type);vue.component({ template : ` div div请登录/div `,props: [ 'post' ],computed : { show Post(){ return abilities . can(' read ',' Post ');} }});
我使用Vue.js和CASL来方便地运行和扩展这些规则,即使将来添加了新的操作或实例。
现在我将带您一步一步地构建这个应用程序。如果你想看,请戳这个Github回购。
我们将权限定义写入一个CommonJS模块,以保证Node的兼容性(Webpack可以让这个模块在客户端使用)。
资源/能力. js
const casl=require(' casl ');module . exports=function defineableties for(user){ return casl。abilityBuilder . define({ subjectname : item=item . type },can={ can(['read ',' create'],' Post ');可以(['更新','删除'],'发布',{ user : user });} );};让我们分析一下这段代码。
作为define方法的第二个参数,我们通过调用can来定义权限规则。该方法的第一个参数是您希望允许的CRUD操作,第二个参数是资源或实例,在本例中是Post。
注意can的第二次调用,我们传递了一个对象作为第三个参数。此对象用于测试用户属性是否与我们提供的用户对象匹配。如果我们不这样做,不仅创作者可以删除帖子,任何人都可以随意删除。
资源/能力. js
.卡斯。AbilityBuilder.define(.can={ can(['read ',' create'],' Post ');可以(['更新','删除'],'发布',{ user : user });});在检查实例以分配权限时,CASL需要知道实例的类型。一种解决方案是将subjectName方法的对象作为define方法的第一个参数,subjectName方法将返回实例的类型。
我们通过在实例中返回type来实现这一点。在定义Post对象时,我们需要确保这个属性存在。
资源/能力. js
.卡斯。abilityBuilder . define({ subjectname : item=item . type },);最后,我们将权限定义封装到一个函数中,这样当我们需要测试权限时,就可以直接传入一个用户对象。在下面的函数中会更容易理解。
资源/能力. js
const casl=require(' casl ');module . exports=function defineableties for(user){ 0.};
介绍Vue和能力插件。这个插件将把CASL添加到Vue的原型中,这样我们就可以在组件中调用它。
将我们的规则引入Vue应用程序(例如:resources/capabilities . js)。
定义当前用户。在实战中,我们通过服务器获取用户数据。在这个例子中,我们只是将其硬编码到项目中。
记住,能力模块导出一个函数,我们称之为defineAbilitiesFor。我们将向这个函数传递一个用户对象。现在,只要我们检测到一个对象,我们就能发现当前用户拥有什么权限。
添加能力插件,这样我们就可以像这样测试组件:这个。$can(.).
src/main.js
从“Vue”导入Vue;从“”导入能力插件。/ability-plugin ';const defineAbilitiesFor=require('./资源/能力’);让用户={ id: 1,name : ' George ' };let ability=defineabilities for(user . id);Vue.use(abilitiesPlugin,能力);
在我们的发布实例中需要两个属性:
类型属性。CASL在capabilities . js中使用subjectName回调来检查正在测试哪个实例。
用户属性。这是海报。请记住,用户只能更新和删除他们的帖子。在main.js中,我们已经通过defineAbilitiesFor(user.id)告诉了CASL当前的用户是谁。CASL要做的是检查用户的ID是否与用户属性匹配。
let Post=[{ type: 'Post ',user: 1,content: '1二手猫,状况良好' },{ type : ' Post ',user: 2,content: '二手浴室壁纸' }];这两个帖子对象中,ID为1的George拥有第一个帖子的更新和删除权限,但没有第二个。
src/组件/Post.vue
模板div br/small post by/small/div button @ click=' del ' delete/button/div/template script从' axios '导入axios;导出默认的{ props: ['post ',' username'],methods: { del() { if (this。$can('delete ',this . post)){ 0.} else { this。$emit('err ','只有帖子的所有者才能删除它!' );}}}}/script stylelang=' scss './style单击“删除”按钮,捕获click事件,并调用del handler。
我们使用CASL通过这个来检查当前用户是否有操作权限。$can('delete ',post)。如果您有权限,请继续。如果没有,则给出错误消息“只有发布者可以删除!”
src/组件/Post.vue
如果(这个。$can('delete ',post)){ axios . get(`/delete/$ { post . id } `,)。然后(RES=}.});}服务器不应该信任客户端的CRUD操作,所以让我们将CASL测试逻辑放入服务器:
server.js
app.get('/delete/:id ',(req,RES)={ let PostID=ParSeint(req。参数。id);让post=post。find(post=post。id===PostID);if (ability.can('delete ',post)){ post=post。过滤器(cur=cur!==post);RES . JSON({ success : true });} else { RES . JSON({ success : false });}});中国飞机服务有限公司是同构(同构)的,服务器上的能力对象就可以从能力。射流研究…中引入,这样我们就不必复制任何代码了!
我认为这个$can('删除,发布)比下面这样优雅得多:
if(用户。id===Post。用户帖子。type===' Post '){ }.}