Разрешения и роли с помощью vuejs и laravel - PullRequest
0 голосов
/ 03 сентября 2018

Вот текущая настройка, которую я имею с CASL. в настоящее время кажется, что он не читает массив правил, который я импортирую в файлility.js. Я также импортировал плагин для умений в файл main.js, если вы хотите это видеть

здесь файл умений .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"}]

1 Ответ

0 голосов
/ 11 сентября 2018

Вам необходимо определить темы и действия, которые можно выполнять по этим темам (например, пользователь может прочитать сообщение переводит -> subject: "post", action: "read"). Когда вы это сделаете, вы можете создать маршрут (или вернуть его как часть ответа аутентификации) для аутентифицированного пользователя на стороне 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 документацию для деталей

...