You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel Voyager中实现用户仅操作自身创建记录的CRUD?

实现Laravel Voyager用户仅操作自身记录的方案

刚接触Voyager的时候我也踩过这个坑——默认权限系统确实是全局的,没法直接按用户过滤记录。不过通过几个简单的步骤就能搞定,让普通用户只能CRUD自己创建的内容,管理员(如果有的话)还能保持全局权限,下面是具体操作:


1. 给目标数据表添加用户关联字段

首先得让你的业务表(比如posts、orders这类)和用户表建立关联,用来标记每条记录的创建者:

  • 生成迁移文件(把[your_table]替换成你的表名):
    php artisan make:migration add_user_id_to_[your_table]_table --table=[your_table]
    
  • 打开迁移文件,添加关联字段:
    public function up()
    {
        Schema::table('[your_table]', function (Blueprint $table) {
            $table->unsignedBigInteger('user_id')->nullable();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });
    }
    
    public function down()
    {
        Schema::table('[your_table]', function (Blueprint $table) {
            $table->dropForeign(['user_id']);
            $table->dropColumn('user_id');
        });
    }
    
  • 运行迁移:
    php artisan migrate
    
  • 在对应模型里添加关联关系:
    // 比如app/Models/Post.php
    public function user()
    {
        return $this->belongsTo(User::class);
    }
    

2. 自动填充创建者ID

要确保用户创建记录时,user_id自动设为当前登录用户的ID,不用手动输入:

  • 在对应模型里添加creating事件监听:
    protected static function booted()
    {
        static::creating(function ($model) {
            // 只有登录用户创建记录时才填充
            if (auth()->check()) {
                $model->user_id = auth()->user()->id;
            }
        });
    }
    
  • 去Voyager的BREAD编辑页面,找到user_id字段,把「可见」「可编辑」都关掉,避免用户手动修改这个值。

3. 列表页只显示当前用户的记录

通过全局作用域过滤列表数据,让用户只能看到自己创建的内容:

  • 还是在对应模型里添加全局作用域(可以和上面的booted方法合并):
    protected static function booted()
    {
        // 上面的creating事件...
    
        static::addGlobalScope('user_filter', function ($query) {
            // 管理员不受限制,如果你不需要管理员角色,直接删掉这个判断
            if (auth()->check() && !auth()->user()->hasRole('admin')) {
                $query->where('user_id', auth()->user()->id);
            }
        });
    }
    

4. 拦截非法的编辑/删除请求

光过滤列表还不够,用户可能通过URL直接访问不属于自己的记录页面,所以要加权限验证:

  • 打开app/Providers/VoyagerServiceProvider.php,在boot方法里添加Voyager的前置钩子:
    public function boot()
    {
        parent::boot();
    
        Voyager::before(function ($action) {
            $currentUser = auth()->user();
            // 跳过管理员和未登录用户
            if (!$currentUser || $currentUser->hasRole('admin')) {
                return;
            }
    
            // 拦截编辑、删除、查看操作
            $restrictedActions = ['edit', 'delete', 'view'];
            if (in_array($action->getAction(), $restrictedActions)) {
                $targetModel = $action->data;
                if ($targetModel->user_id != $currentUser->id) {
                    abort(403, '你没有权限操作这条记录');
                }
            }
        });
    }
    

5. 最后检查BREAD权限

确保Voyager的BREAD配置里,给用户开放了该模型的CRUD权限——我们是在默认权限基础上做过滤,不是直接关掉权限。


这样设置完之后,普通用户就只能看到和操作自己创建的记录了,管理员依然能查看所有内容。如果你的系统不需要管理员角色,直接删掉所有判断hasRole('admin')的逻辑就行。

内容的提问来源于stack exchange,提问作者Darek P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:30:39