Form Requests

Authorizing and Preparing Form Requests

Before validating, a form request runs prepareForValidation(), which may rewrite the input, and then authorize(), which returns a bool or a gate Response carrying a message for the 403:

The two hooks in StoreProductRequestCSS
public function authorize(): Response
{
    return $this->user()->is_admin
        ? Response::allow()
        : Response::deny('Only staff can change the catalog.');
}
protected function prepareForValidation(): void
{
    $this->merge([
        'sku' => Str::upper((string) $this->sku),
        'price' => ltrim((string) $this->price, '$'),
    ]);
}
Output
$ U='-u reader@example.com:secret123'; N='name=Refactoring&category_id=1&format=hardcover'
$ curl -s $U -H "$H" -H "$J" -o r.json -w '%{http_code} ' -d "$N&sku=BK-1005&price=47.5" \
    $B/products; jq -r .message r.json
403 Only staff can change the catalog.
$ curl -s $A -H "$H" -o /dev/null -w '%{redirect_url}\n' -d "$N&sku= bk-1005 &price=\$47.50" \
    $B/products
http://127.0.0.1:8308/products/3

The reader was refused before any rule, or its unique query, ran. The admin's bk-1005 and $47.50 were stored as BK-1005 and 47.50 (the global TrimStrings middleware had removed the spaces). Beyond a flag, call a policy: $this->user()->can('create', Product::class) (Authorization). after() returns closures that see the whole validator, for cross-field checks.