【问题标题】:Vue.js with Laravel Permission具有 Laravel 权限的 Vue.js
【发布时间】:2019-04-18 04:01:10
【问题描述】:

我正在将 Laravel Permission API 与 Vue.JS 前端集成。我正在使用 https://github.com/spatie/laravel-permission 库获取 Laravel 权限。我不明白如何在 Vue JS 前端检查权限(在 Laravel 刀片中,我使用 @Can 检查权限)。

【问题讨论】:

  • 我也面临同样的问题。

标签: laravel vue.js user-permissions


【解决方案1】:

我会做一个 ajax 调用来检查权限,就像这样,但当然你需要修改它以满足你的需要。

路线:

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

控制器:

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

Vue:(如果你想同步做),这是一个简单的例子(Vue global mixin),你可以把它变成Vue指令或组件。

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

然后每次你想检查权限,你就可以这样做

<el-input v-if="can('write-stuff')"> </el-input>

【讨论】:

  • 假设页面上有 100 个按钮。然后你进入页面...... Boom 100 axios 获取请求。我认为这是一种不好的做法。
  • @IvanDavletshin 确实如此,但在这种情况下,您应该将 v-if 放在包含这 100 个按钮的公共 div 上
  • 但这只有在所有按钮的 v-if 都相同时才有效。这也可以以某种方式缓存,以便能够放置按钮,而不仅仅是一个 div。但是,如果按钮之间的能力应该不同怎么办。我现在正在将类似于 cancan 的集成实现到 Laravel 和 Vue 方面。所以他们都有相同的规则。这对我来说看起来更正确。
  • 你好书艺,如果无法访问元素,如何隐藏元素?
  • 这不起作用,因为 get 请求是异步操作。返回hasAccess 只会产生未定义的结果。如果你在 mixin 中使用 async/await,它只会返回一个 Promise 而不是解析。
【解决方案2】:

我确实在做同样的事情。我正在考虑添加一个 custom Vue directive 来检查 Laravel.permissions 数组。

甚至可以这么简单

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

我没有测试过这段代码。只是在这里集思广益。

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

我可以通过这种方式持有权限:

window.Laravel = <?php echo json_encode([
                'csrfToken' => csrf_token(),
                'userId' => Auth::user()->id,
                'permissions' => Auth::user()->permissions()->pluck('name')->toArray()
            ]); ?>

【讨论】:

  • 如何在 vue js 中获取 laravel 权限数组?
  • 我猜你只是在刀片模板中的某处使用&lt;script type="text/javascript"&gt; window.Laravel = { permissions: Json.parse('@json(\Auth::user()-&gt;permissions)') };&lt;/script&gt;(很可能是layout.blade.php)。
  • 我想你会想要设置一个端点,你可以从 vue 前端点击它,它会给你用户权限,否则,在上面的例子中,是什么阻止了用户编辑他们的权限并获得对所有内容的访问权限。
  • @wheelmaker 这无关紧要,因为需要许可的所有内容仍将位于端点后面,仅用于前端布局
  • 使用安全吗?
【解决方案3】:

偶然发现了这个问题,我想分享一下我发现和实现的内容。

  1. 在 spatie/laravel-permission 正在使用的 User 模型上添加访问器
    public function getAllPermissionsAttribute() {
       $permissions = [];
         foreach (Permission::all() as $permission) {
           if (Auth::user()->can($permission->name)) {
             $permissions[] = $permission->name;
           }
         }
       return $permissions;
    }
  1. 在您的全局页面或布局页面上,将访问者的权限传递给 javascript。
    <script type="text/javascript">
       @auth
          window.Permissions = {!! json_encode(Auth::user()->allPermissions, true) !!};
       @else
          window.Permissions = [];
       @endauth
    </script>
  1. 在 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;
        }
    })

在这里,您正在检查您在指令中提供的权限是否在 laravel 的权限数组中。 如果找到则隐藏else显示的元素,这个函数就像一个v-if。

  1. 在您的组件上像这样使用它 - “add_items”是您的许可
    <button type="button" v-can="'add_items'"></button>

此解决方案来自 this,但我使用指令而不是 mixin。 从上面的@Ismoil Shifoev 评论中得到了指令的想法。

【讨论】:

    【解决方案4】:

    你可以在 Vuejs 中使用这种格式来获取 Laravel 权限:

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

    向用户模型添加函数以获取所有用户权限和角色,如下所示:

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

    将此数据传递给 HTML 标头中的 JavaScript:

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

    app.js 文件中添加全局 Vuejs can 函数来检查用户权限和 is 函数来检查用户角色:

    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

    【讨论】:

      【解决方案5】:

      我会选择 Ralph 解决方案。但我发现自己更好地使用。此函数用于获取权限。

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

      稍微简洁一点,因为我倾向于使用角色而不是每个用户的特定权限,所以这个解决方案应该也可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-08
        • 2016-06-02
        • 2021-05-01
        • 2019-05-03
        • 2019-10-24
        • 2011-02-11
        • 2021-05-27
        • 2015-05-11
        相关资源
        最近更新 更多