首页 > 解决方案 > 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
    }
 })
}

rulesrest-api获取登录和格式化并将其保存为localStoragecasl/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>

但它正在返回false
一些帮助非常感谢!
我是这样保存rules在此处输入图像描述

标签: vue.jsvuejs2casl

解决方案


我正在使用@casl/ability@5.2.2@casl/vue@1.2.2
正如@SergiiStotskyi 在评论中所说

如果您得到 null ,relevantRuleFor则意味着 casl 不是提供的操作/主题对的规则。据我所知,rule物体的形状是错误的。action 在 v4 中被弃用并在 v5 中被删除。尝试替换actionsaction

更改actionsaction有效后。

谢谢@SergiiStotskyi
Casl 是一个很棒的图书馆


推荐阅读