问题描述
我在 vue cli 项目中使用 @casl/vue 插件进行用户权限管理,如 casl 插件作者 sample(vue-blog) 的示例存储库所示。这是我的代码
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
}
})
}
我在登录和格式化时从 rest-api 获取 rules
,并以 casl/vue 格式 localStorage
将其保存到 {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>
但它正在返回 false
非常感谢一些帮助!
我已经像这样保存了 rules
解决方法
我使用的是 win_shell: Start-ScheduledTask -TaskName {{task}}
win_shell: Stop-ScheduledTask -TaskName {{task}}
和 @casl/ability@5.2.2
正如@SergiiStotskyi 在评论中所说
如果 @casl/vue@1.2.2
为 null,则表示 casl 不是提供的操作/主题对的规则。据我所知,relevantRuleFor
对象的形状是错误的。动作在 v4 中被弃用,在 v5 中被删除。尝试将 rule
替换为 actions
将 action
更改为 actions
后有效。
谢谢@SergiiStotskyi
Casl 是一个很棒的库