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

Laravel Policy限制Filament批量删除失效,非管理员仍可删他人内容

Laravel删除权限限制问题解决方案

1. 补全删除策略方法

你只实现了forceDelete策略,但如果系统默认使用软删除(调用delete()),还需要在SliderPolicy中添加delete方法,确保两种删除操作都受权限控制:

public function delete(User $user, Slider $slider): bool
{
    return $user->hasRole("Admin") || $slider->created_by === $user->id;
}

同时确认AuthServiceProvider已正确注册该策略:

protected $policies = [
    Slider::class => SliderPolicy::class,
];

2. 修复批量删除的权限漏洞

批量删除不会自动触发单模型的策略校验,需要手动处理:

控制器层面过滤可删除数据

在批量删除的控制器方法中,先筛选出当前用户有权限删除的记录,再执行删除:

public function batchDestroy(Request $request)
{
    $sliderIds = $request->input('ids');
    $user = $request->user();

    $query = Slider::whereIn('id', $sliderIds);
    // 非管理员仅保留自己创建的记录
    if (!$user->hasRole('Admin')) {
        $query->where('created_by', $user->id);
    }

    // 根据业务需求选择delete(软删)或forceDelete(硬删)
    $query->forceDelete();

    return redirect()->back()->with('success', '批量删除完成');
}

视图层面控制按钮显示

如果非管理员不需要看到批量删除按钮,直接在Blade视图中做权限判断:

@if(auth()->user()->hasRole('Admin'))
    <button type="button" class="btn btn-danger" id="batchDeleteBtn">批量删除</button>
@endif

如果需要更精细的控制(仅当选中的所有记录都是自己创建时才显示按钮),可以加前端判断:

<script>
const batchBtn = document.getElementById('batchDeleteBtn');
batchBtn.style.display = 'none';

// 监听复选框选择事件
document.querySelectorAll('input[name="slider_ids[]"]').forEach(checkbox => {
    checkbox.addEventListener('change', () => {
        const selectedCheckboxes = Array.from(document.querySelectorAll('input[name="slider_ids[]"]:checked'));
        const currentUserId = {{ auth()->id() }};
        const isAdmin = {{ auth()->user()->hasRole('Admin') ? 'true' : 'false' }};

        // 非管理员需确认所有选中项都是自己创建的
        const canBatchDelete = isAdmin || selectedCheckboxes.every(box => box.dataset.createdBy == currentUserId);
        batchBtn.style.display = canBatchDelete ? 'block' : 'none';
    });
});
</script>

注意:需要给复选框添加data-created-by="{{ $slider->created_by }}"属性。

3. 确保单条删除的权限校验生效

在单条删除的控制器方法中,必须调用authorize方法触发策略校验:

public function destroy(Slider $slider)
{
    // 校验delete权限(对应策略中的delete方法)
    $this->authorize('delete', $slider);
    $slider->forceDelete(); // 或delete()
    return redirect()->back()->with('success', '删除成功');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:17:19