使用 vuejs 和 laravel 的权限和角色

Posted

技术标签:

【中文标题】使用 vuejs 和 laravel 的权限和角色【英文标题】:Permissions and Roles using vuejs and laravel 【发布时间】:2019-02-08 17:07:31 【问题描述】:

这是我使用 CASL 的当前设置。目前它似乎没有读取我要导入到 ability.js 文件中的规则数组。如果你也想看的话,我也将能力插件导入到 main.js 文件中

这是ability.js文件

import  Ability  from '@casl/ability'

export const ability = new Ability()

export const abilityPlugin = (store) => 
  ability.update(store.state.rules)

  return store.subscribe((mutation) => 
    switch (mutation.type) 
    case 'createSession':
      ability.update(mutation.payload.rules)
      break
    case 'destroySession':
      ability.update([ actions: 'read', subject: 'all' ])
      break
    
  )

这里是调用规则列表的商店

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import storage from './utils/storage'
import  abilityPlugin, ability as appAbility  from './utils/ability'

export const ability = appAbility
Vue.use(Vuex)
axios.defaults.baseURL = 'http://todo-laravel.test/api'

export default new Vuex.Store(
  plugins: [
    storage(
      storedKeys: ['rules'],
      destroyOn: ['destroySession']
    ),
    abilityPlugin
  ],
  state: 
    rules: '',
    token: localStorage.getItem('access_token') || null,
  ,
  mutations: 
    createSession(state, role) 
      state.rules = role[0]
    ,
    destroySession(state) 
      state.rules = ''
    ,
    retrieveToken(state, token) 
      state.token = token
    ,
    destroyToken(state) 
      state.token = null
    ,
  ,
  actions: 
    destroyToken(context) 
      axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token

      if (context.getters.loggedIn) 
        return new Promise((resolve, reject) => 
          axios.post('/logout')
          .then(response => 
            localStorage.removeItem('access_token')
            context.commit('destroyToken')
            context.commit('destroySession')
            resolve(response)
          )
          .catch(error => 
            localStorage.removeItem('access_token')
            context.commit('destroyToken')
            reject(error)
          )
        )
      
    ,
    retrieveToken( commit, dispatch , credentials) 

      return new Promise((resolve, reject) => 
          axios.post('/login', 
              username: credentials.username,
              password: credentials.password,
          )
          .then(response => 
              const token = response.data.access_token

              localStorage.setItem('access_token', token)
              commit('retrieveToken', token)
              dispatch('retrieveRules')
              resolve(response)
          )
          .catch(error => 
              console.log(error)
              reject(error)
          )
      )
    ,
    retrieveRules(context) 
      axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token

      return new Promise((resolve, reject) => 
          axios.get('/rules')
          .then(response => 
              console.log(response.data)
              context.commit('createSession', response.data)
              resolve(response)
          )
          .catch(error => 
              console.log(error.response.data)
              reject(error)
          )
      )
    ,

这是保存在存储中的规则数组

[id: 1, role_id: 3, action: "Manage", subject: "All"]

【问题讨论】:

基本上你创建名为角色和权限的表,你创建权限和角色之间以及角色和用户之间的关系,然后你使用策略:laravel.com/docs/5.6/authorization#generating-policies,如果你想要一个例子让我知道 Token scopes 用于此目的。 Passport 在后台使用 JWT,因此您还可以在每个有效负载中添加额外数据。 【参考方案1】:

您需要定义可以在该主题上执行的子任务和操作(例如,用户可以阅读帖子翻译为 -> 主题:“帖子”,操作:“阅读”)。 执行此操作时,您可以在 API 端为经过身份验证的用户创建路由(或将其作为身份验证响应的一部分返回),该路由返回用户特定的操作。例如:

如果用户是管理员,他可以做任何事情,所以响应应该是:


  "rules": [
     "action": "manage", "subject": "all"  
  ]

如果用户是团队成员,那么他有一些受限的权限(假设他只能读取设置):


  "rules": [
     "action": "read", "subject": "Settings"  
  ]

在用户界面方面:

如果你不使用 Vuex:

// main.js
import  abilitiesPlugin  from '@casl/vue'
import Vue from 'vue'

Vue.use(abilitiesPlugin);

// inside LoginComponent

  methods: 
    login() 
      return this.http.post(...)
        .then(respose => this.$ability.update(response.data.rules)
    
  

如果你使用 Vuex:

// main.js
import  abilitiesPlugin  from '@casl/vue'
import Vue from 'vue'
import ability from './services/ability';

Vue.use(abilitiesPlugin, ability);


// services/ability.js
import  Ability  from '@casl/ability';

export default new Ability()


// store.js
import ....
import ability from './services/ability'

const updateAbilities = (store) => 
  ability.update(store.state.rules) // take rules from your state structure

  return store.subscribe((mutation) => 
    switch (mutation.type) 
    case 'login':
      ability.update(mutation.payload.rules)
      break
    case 'logout':
      ability.update([ actions: 'read', subject: 'all' ]) // read only mode
      // or `ability.update([])` to remove all permissions
      break
    
  )


export default new Vuex.Store(
  plugins: [
    updateAbilities
  ],
  // ... your store declaration
)

您可以查看https://github.com/stalniy/casl-vue-api-example,这是一个 Vue、CASL 和 Rails 集成的示例,以了解一些详细信息

更新

稍后在所有组件中只需使用$can 函数或<can> 组件来检查权限。详情请查看CASL Vue documentation

【讨论】:

抱歉,您的帖子回复晚了。过去几天我一直在玩 casl,但遇到了问题。我正在返回一组规则,但它似乎没有被ability.js 文件读取。详情请查看原帖

以上是关于使用 vuejs 和 laravel 的权限和角色的主要内容,如果未能解决你的问题,请参考以下文章

laravel-如何在 5.1 中使用 zizaco 获得具有所有角色和所有权限的用户?

Laravel 和 MongoDB 以及高级角色/权限系统

Laravel 角色和权限操作

Laravel 5.3 Eloquent 关系 - 用户、角色、页面和权限

Laravel 角色和权限包

Laravel 权限和角色与 Gate/Can