Casl/vue $can 函数返回 false,但用户拥有该权限
Casl/vue $can function is returning false, but user has that permission
我在 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
我正在使用 @casl/ability@5.2.2
和 @casl/vue@1.2.2
正如@SergiiStotskyi
的评论中所说
If you get null for relevantRuleFor
it means that casl doesn’t a rule for provided action/subject pair. From what I can tell is that the shape of rule
object is wrong. actions was deprecated in v4 and removed in v5. Try to replace actions
with action
将 actions
更改为 action
后有效。
谢谢@SergiiStotskyi
Casl 是一个很棒的图书馆
我在 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
我正在使用 @casl/ability@5.2.2
和 @casl/vue@1.2.2
正如@SergiiStotskyi
If you get null for
relevantRuleFor
it means that casl doesn’t a rule for provided action/subject pair. From what I can tell is that the shape ofrule
object is wrong. actions was deprecated in v4 and removed in v5. Try to replaceactions
withaction
将 actions
更改为 action
后有效。
谢谢@SergiiStotskyi
Casl 是一个很棒的图书馆