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
相关产品推荐
相关产品推荐

