修复Laravel表单数组验证递归限制

时间:2017-12-05 05:15:57

标签: php laravel validation laravel-validation

Laravel表单验证很棒,只是在使用数组表示法时它不会过滤掉无关键。

我在控制器中输入表单请求。

public function saveEdit(Post\EditRequest $request)
{
    $valid = $request->validated();
}

如果我的表单包含address_1address_2,并且用户欺骗address_3,则欺骗的值不会出现在$valid中。

但是,如果我的表单使用数组表示法,例如venue[address_1]venue[address_2],那么用户可以欺骗venue[address_3],它将出现在$valid中。

还有其他人遇到过这个吗?你是怎么处理它的?

表单请求类上的validated()方法似乎需要递归操作。

2 个答案:

答案 0 :(得分:1)

你可以使用点符号

 public function rules()
    {
        return [
            'venue.address_1' => 'required',
            'venue.address_2' => 'required',
            'venue.address_3'=>'required',
        ];
    }

如果您使用动态数组,则可以通过

执行此操作
 public function rules()
     {
         return [
             'venue.address_.*' => 'required'
         ];
     }

答案 1 :(得分:1)

不幸的是,Laravel还没有内置支持验证数组,只有数组。为此,我们需要添加custom validation rules

但是,使用$fillable模型属性和array_only()辅助函数等替代保护,创建这些规则对于非常不可能的边缘情况来说是一项额外的工作。我们为预期用户错误和清理提供验证反馈,以保护我们的数据免受意外输入的影响。

如果用户欺骗了密钥,只要我们不保存密钥,或者我们将其过滤掉,如果他们没有看到相当有效的验证信息,他们就不会太担心 - 验证一个不应该存在的字段是没有意义的。

为说明清理的工作原理,这里有Venue模型声明其可填充属性:

class Venue extends Model 
{
    protected $fillable = [ 'address_1', 'address_2' ]; 
    ...
}

现在,如果恶意用户试图欺骗数组中的另一个属性:

<input name="venue[address_1]" value="...">
<input name="venue[address_2]" value="...">
<input name="venue[address_3]" value="spoof!">

...我们直接使用输入数组来更新模型:

public function update(Request $request, $venueId)
{
    $venue = Venue::find($venueId); 
    $venue->update($request->venue);
    ...
}

...模型将从输入数组中去掉额外的address_3元素,因为我们从未将其声明为可填充字段。换句话说,该模型清理了输入。

在某些情况下,我们可能需要在不使用Eloquent模型的情况下简单地清理数组元素。我们可以使用array_only()函数(或Arr:only())来执行此操作:

$venueAddress = array_only($request->venue, [ 'address_1', 'address_2' ]);