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

Laravel中如何按角色保护表单字段,防范前端篡改?

解决表单字段后端权限验证的方案

你担心前端隐藏字段被篡改提交的问题非常关键,后端验证是必须的,用Middleware不是最优解,更推荐在控制器或表单请求类里处理——因为权限判断和字段处理和业务逻辑更贴近,下面是具体实现步骤:

1. 过滤请求字段,只保留用户有权限操作的内容

先明确两类字段:

  • 普通用户可提交的字段:name, fathers_last_name, mothers_last_name, email, curp, rfc, imss, age, telefono, birth_date, gender_id, street, interior_number, exterior_number, zip_code, active
  • 仅管理员(拥有assing.employee权限)可操作的字段:company_id, team_id, employe_code, start_date

在控制器的store方法里,根据用户权限筛选允许的字段:

public function store(Request $request)
{
    // 基础允许字段
    $allowedFields = [
        'name', 'fathers_last_name', 'mothers_last_name', 'email',
        'curp', 'rfc', 'imss', 'age', 'telefono', 'birth_date',
        'gender_id', 'street', 'interior_number', 'exterior_number',
        'zip_code', 'active'
    ];

    // 如果用户有管理员权限,追加专属字段
    if ($request->user()->can('assing.employee')) {
        $allowedFields = array_merge($allowedFields, [
            'company_id', 'team_id', 'employe_code', 'start_date'
        ]);
    }

    // 只保留允许的字段,过滤掉用户篡改提交的非法字段
    $validatedData = $request->only($allowedFields);

    // 后续的创建逻辑
    $employee = Employee::create($validatedData);

    return redirect()->route('employee.index')->with('success', 'Empleado creado exitosamente');
}

2. 分权限设置验证规则

如果需要对字段做校验,也要根据权限调整规则:

// 基础验证规则
$rules = [
    'name' => 'required|string|max:255',
    'email' => 'required|email|unique:employees',
    // 其他普通字段的验证规则...
];

// 管理员额外验证规则
if ($request->user()->can('assing.employee')) {
    $rules = array_merge($rules, [
        'company_id' => 'required|exists:companies,id',
        'team_id' => 'required|exists:teams,id',
        'start_date' => 'required|date',
    ]);
}

// 执行验证
$validatedData = $request->validate($rules);

3. 更优雅的方式:使用FormRequest

如果项目规范要求,可以创建专门的表单请求类(比如StoreEmployeeRequest),把权限判断和验证逻辑封装进去:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;

class StoreEmployeeRequest extends FormRequest
{
    public function authorize()
    {
        // 基础访问权限:所有登录用户都能提交表单
        return Auth::check();
    }

    public function rules()
    {
        $rules = [
            // 普通字段验证规则...
        ];

        if ($this->user()->can('assing.employee')) {
            $rules = array_merge($rules, [
                // 管理员字段验证规则...
            ]);
        }

        return $rules;
    }

    // 提前过滤字段,确保非法字段不会进入验证环节
    protected function prepareForValidation()
    {
        $allowedFields = [/* 普通字段列表 */];

        if ($this->user()->can('assing.employee')) {
            $allowedFields = array_merge($allowedFields, [/* 管理员字段列表 */]);
        }

        $this->merge($this->only($allowedFields));
    }
}

额外注意事项

  • 确保模型的$fillable属性包含所有可能被赋值的字段,避免批量赋值报错
  • 永远不要依赖前端的隐藏/禁用状态,后端必须做最终的权限校验和字段过滤

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:17:04