Vue.js with Laravel Permission

后端 未结 5 605
旧时难觅i
旧时难觅i 2020-12-31 22:38

I am in the process of integrating Laravel Permission API with Vue.JS frontend. I am using https://github.com/spatie/laravel-permission library for Laravel Permission. I am

相关标签:
5条回答
  • 2020-12-31 22:43

    I will do a ajax call to check for permissions instead , something like this, but of cours eyou need to modify it to cater your needs.

    Routes:

    Route::get('/permission/{permissionName}', 'PermissionController@check');
    

    Controller:

    function check($permissionName) {
       if (! Auth::user()->hasPermissionTo($permissionName)) {
            abort(403);
       }
       return response('', 204);
    }
    

    Vue: (if you wanna do this synchronously), this is a simple example (Vue global mixin), you can turn this into Vue directive or component.

    Vue.mixin("can", (permissionName) => {
        let hasAccess;
        axios.get(`/permission/${permissionName}`)
            .then(()=> {
                hasAccess = true;
            }
            .catch(()=> {
                hasAccess = false;
            };
        return hasAccess;
    });
    
    

    And then everytime you wanna check permission, you can just do

    <el-input v-if="can('write-stuff')"> </el-input>
    
    0 讨论(0)
  • 2020-12-31 22:44

    I would go with Ralph solution. But I find myself better using. This function to fetch the Permissions.

    public function getAllPermissionsAttribute() {
        return Auth::user()->getAllPermissions()->pluck('name');
    }
    
    

    Just a bit cleaner, and since I tend to use Roles instead of particular permissions for each User, this solution should work as well.

    0 讨论(0)
  • 2020-12-31 22:58

    I'm literally working on this exact same thing. I'm thinking of adding a custom Vue directive that would check against the Laravel.permissions array.

    It might even be as simple as

     Vue.directive('can', function (el, binding) {
      return Laravel.permissions.indexOf(binding) !== -1;
    })
    

    I haven't tested this code. Just brainstorming here.

    <button v-can="editStuff">You can edit this thing</button>
    

    I can hold permissions this way:

    window.Laravel = <?php echo json_encode([
                    'csrfToken' => csrf_token(),
                    'userId' => Auth::user()->id,
                    'permissions' => Auth::user()->permissions()->pluck('name')->toArray()
                ]); ?>
    
    0 讨论(0)
  • 2020-12-31 23:01

    You can use this format in Vuejs for Laravel Permission:

    <div v-if="can('edit post')">
      <!-- Edit post form -->
    </div>
    
    <div v-if="is('super-admin')">
      <!-- Show admin tools -->
    </div>
    

    add function to User Model to get all user permissions&roles like this:

    class User extends Authenticatable
    {
        // ...
    
        public function jsPermissions()
        {
            return json_encode([
                    'roles' => $this->getRoleNames(),
                    'permissions' => $this->getAllPermissions()->pluck('name'),
                ]);
        }
    }
    

    pass this data to JavaScript in HTML header:

    <script type="text/javascript">
        window.Laravel = {
            csrfToken: "{{ csrf_token() }}",
            jsPermissions: {!! auth()->check()?auth()->user()->jsPermissions():null !!}
        }
    </script>
    

    in app.js file add global Vuejs can function to check user permissions and is function to check user roles:

    Vue.prototype.can = function(value){
        return window.Laravel.jsPermissions.permissions.includes(value);
    }
    Vue.prototype.is = function(value){
        return window.Laravel.jsPermissions.roles.includes(value);
    }
    

    https://github.com/ahmedsaoud31/laravel-permission-to-vuejs

    0 讨论(0)
  • 2020-12-31 23:06

    Just stumbled upon this problem and I would like to share what I found and implemented.

    1. Add an accessor on the User model the spatie/laravel-permission is using
        public function getAllPermissionsAttribute() {
           $permissions = [];
             foreach (Permission::all() as $permission) {
               if (Auth::user()->can($permission->name)) {
                 $permissions[] = $permission->name;
               }
             }
           return $permissions;
        }
    
    1. On your global page or layout page pass the permission from the accessor to the javascript.
        <script type="text/javascript">
           @auth
              window.Permissions = {!! json_encode(Auth::user()->allPermissions, true) !!};
           @else
              window.Permissions = [];
           @endauth
        </script>
    
    1. Create a global directive on resources/js/app.js
        Vue.directive('can', function (el, binding, vnode) {
    
            if(Permissions.indexOf(binding.value) !== -1){
               return vnode.elm.hidden = false;
            }else{
               return vnode.elm.hidden = true;
            }
        })
    

    Here you are checking if the permission you supplied on the directive is on the permission array from laravel. If found then it will hide the element else show, this function is like a v-if.

    1. Use it like this on your component - "add_items" is your permission
        <button type="button" v-can="'add_items'"></button>
    

    This solution is from this but instead of a mixin, I use a directive. Got the idea of directive from @Ismoil Shifoev comment above.

    0 讨论(0)
提交回复
热议问题