vue.js - Casl/vue $can 函数返回 false,但用户拥有该权限
问题描述
我在 vue cli 项目中使用@casl/vue插件进行用户权限管理,如casl plugin author sample(vue-blog)的这个示例 repo 所示。这是我的代码
ability.js
export default (store) => {
const ability = store.getters.ability
ability.update(store.state.rules);
return store.subscribe((mutation) => {
switch (mutation.type) {
case 'ROOT_LOGIN_SUCCESS':
var formattedRules = [];
if (mutation.payload.permissions.length > 0) {
formattedRules = mutation.payload.permissions.map(perm => {
let formattedObj = {};
formattedObj.actions = perm.substr(0, perm.indexOf(' '));
formattedObj.subject = perm.substr(perm.indexOf(' ') + 1);
return formattedObj;
})
}
console.log(formattedRules)
ability.update(formattedRules);
break
case 'ROOT_LOGOUT_SUCCESS':
ability.update([{actions: 'read', subject: 'all'}])
break
}
})
}
我rules
从rest-api获取登录和格式化并将其保存为localStorage
casl/vue 格式{actions: 'someAction', subject: 'someSubject'}
。这是
storage.js
export default (options) => (store) => {
if (localStorage.state) {
const storedState = JSON.parse(localStorage.state)
store.replaceState(Object.assign(store.state, storedState))
}
return store.subscribe((mutation, state) => {
if (options.destroyOn && options.destroyOn.indexOf(mutation.type) !== -1) {
return localStorage.removeItem('state')
}
const newState = options.storedKeys.reduce((map, key) => {
map[key] = state[key]
return map
}, {});
localStorage.state = JSON.stringify(newState)
})
}
和store.js
/*
* FOR USER PERMISSIONS MANAGEMENT ON UI */
import {Ability} from '@casl/ability'
import abilityPlugin from "@/shared/store/ability"
import storage from "@/shared/store/storage";
...
export default new Vuex.Store({
plugins: [
storage({
storedKeys: ['token', 'rules'],
destroyOn: ['ROOT_LOGOUT_SUCCESS']
}),
abilityPlugin
],
...
mutations: {
ROOT_LOGIN_SUCCESS(state, data) {
let formattedRules = [];
if (data.permissions.length > 0) {
formattedRules = data.permissions.map(perm => {
let formattedObj = {};
formattedObj.actions = perm.substr(0, perm.indexOf(' '));
formattedObj.subject = perm.substr(perm.indexOf(' ') + 1);
return formattedObj;
})
}
state.rules = formattedRules;
state.token = data.token;
},
ROOT_LOGOUT_SUCCESS(state) {
state.rules = [];
},
},
...
getters: {
ability() {
return new Ability()
}
},
}
main.js
/*
* FOR USER PERMISSIONS MANAGEMENT ON UI */
import {abilitiesPlugin, Can} from '@casl/vue'
Vue.use(abilitiesPlugin, store.getters.ability)
Vue.component('Can', Can);
在 Vue 组件模板中,我像这样使用它
index.vue
<v-btn
v-if="$can('delete', 'department')"
color="error"
dark
@click="uiShowConfirm({content: 'Are you sure?',
callBack: deleteConfirmed})"
>
<v-icon class="mr-2">mdi-delete</v-icon>
Delete
</v-btn>
解决方案
我正在使用@casl/ability@5.2.2
,@casl/vue@1.2.2
正如@SergiiStotskyi 在评论中所说
如果您得到 null ,
relevantRuleFor
则意味着 casl 不是提供的操作/主题对的规则。据我所知,rule
物体的形状是错误的。action 在 v4 中被弃用并在 v5 中被删除。尝试替换actions
为action
更改actions
为action
有效后。
谢谢@SergiiStotskyi
Casl 是一个很棒的图书馆
推荐阅读
- html - CSS:绝对位置的表格溢出问题
- angular - 如何指定流以使用 MS Graph 将文件上传到 OneDrive
- python - 使用 spacy 将实体替换为实体标签
- git - 我可以从结束的 git rebase -i 中获取待办事项列表吗?
- docker - 在 Raspberry Pi 4 上,“FROM”基础镜像 golang:latest 和 arm32v7/golang:latest 有什么不同?
- javascript - PHP MySQL PayPal 集成 - 除非手动输入金额,否则 PayPal 按钮不起作用
- java - 解析 BufferedReader 对象时的问题
- android - @SuppressWarnings("unused") 给出警告:Android Studio 更新后的冗余抑制
- javascript - 我想一次打开一个显示/隐藏加减表
- javascript - 有没有办法在 vscode 扩展中按键盘运行命令?