Laravel 5.8 验证竞争条件

Posted

技术标签:

【中文标题】Laravel 5.8 验证竞争条件【英文标题】:Laravel 5.8 Validation Race Condition 【发布时间】:2020-12-26 14:49:33 【问题描述】:

我在控制器内的 POST 请求方法上有这个验证规则:

class CreateOrderController extends Controller

    public function create(Request $request)
    
        $this->validate($request, [
            'store_id' => $request->order_type === OrdersTypeConstants::P2P  ? "" : "required|" . 'exists:stores,id',
            'p2p_type' => [Rule::in([OrdersTypeConstants::P2PCOURIER, OrdersTypeConstants::P2PPURCHASE])],
            'items' => 'required_if:p2p_type,'.OrdersTypeConstants::P2PPURCHASE.'|array',
            'items.*.id' => 'nullable|numeric',
            'items.*.quantity' => 'nullable|integer|min:1',
            'items.*.adjustment' => 'nullable|numeric',
            'items.*.image' => 'nullable|string',
            'items.*.addons' => 'array',
            'items.*.reward_applied' => 'boolean',
            'items.*.replacement_strategy.type' => [
                'string',
                Rule::in([ItemReplacementStrategyConstants::REMOVE,ItemReplacementStrategyConstants::BEST_MATCH, ItemReplacementStrategyConstants::SPECIFIC])
            ],
            'items.*.replacement_strategy.quantity' => 'integer|min:1',
            'items.*.replacement_strategy.item_id' => 'numeric',
            'address_id' => 'exists:addresses,id,user_id,' . $client_id,
            'address_id_p1' => 'exists:addresses,id,user_id,' . $client_id,
            'use_cash_deposit' => 'boolean',
        ]);

有时它会返回The store id field is required,即使它实际上是发送,您可以在错误日志中看到:

仅在生产环境中随机发生 - 并非始终如一地发生,仅在 firebase 上报告。

为什么会这样?

【问题讨论】:

你的 validate() 里面有什么?我没有看到你使用 Request::validate() 或 Validator::make() @AlzafanChristian 控制器有一个 validate 方法,您应用程序中的基本控制器使用 ValidatesRequest 特征 @lagbox 是的,抱歉,完全忘记了 app/Http/Controllers/Controller 中的控制器有 ValidatesRequests,我并不总是扩展那个控制器 如果您在验证器之前记录 $request->all() ,那里是否存在值?我不明白为什么不会,但只是为了确定。 这可能是包含在原始帖子中的有用信息。 【参考方案1】:

发生在我身上好几次了。问题一直是无效的 JSON。 你可以验证你的here。

当 Laravel 遇到无效的 JSON 时,它只是忽略它,并假定有效负载为空。

它在store_id is required 上给您一个验证错误的事实并非巧合。您的框架设置为在第一个失败的规则上停止,而这条规则恰好是 store_id => 'required'

【讨论】:

【参考方案2】:

检查 request()->all() 是否有任何数据(您的 json 可能无效)

【讨论】:

以上是关于Laravel 5.8 验证竞争条件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JWT API - Laravel 5.8 上验证用户群?

Laravel 5.8 验证 - 始终遵守任何规则

Laravel 5.8 有条件地插入 sql 片段

Laravel 5.8 中 hasMany 关系的条件

Laravel 5.8 验证在使用 Passport 失败后返回首页

如何在 laravel 5.8 或 6 中制作通用自定义包进行身份验证。*