Gate Responses

Gate Responses and Inline Authorization

A rule may return an Illuminate\Auth\Access\Response instead of a bool. Response::deny('...') adds a message, denyWithStatus(404) changes the status, and denyAsNotFound() hides the record behind a 404. Gate::allows() still returns a bool, Gate::inspect() returns the Response, and Gate::authorize() throws an AuthorizationException, rendered as a 403 with the message.

Requests go to php artisan serve --port=8315, with a cookie jar per user from a minimal /login route that calls Auth::attempt() (Manually Authenticating Users). try prints the status and JSON body; Sec-Fetch-Site satisfies CSRF protection (CSRF Protection), and APP_DEBUG=false hides traces:

$ B=http://127.0.0.1:8315; H='Sec-Fetch-Site: same-origin'; J='Accept: application/json'

$ login() { curl 3,008  -s -c $1.jar -H "$H" -d "email=$1@example.com&password=secret123" $B/login; }

$ try() { curl -s -o r.json -w '%{http_code} ' -H "$H" -H "$J" "$@"; jq 133,477  -c . r.json; }

$ for u in ann ben cal sam ada; do login $u; done

$ try -b ann.jar -X POST $B/orders/1/refund

403 {"message":"Only staff can issue refunds."}

$ try -b sam.jar -X POST $B/orders/1/refund

200 {"id":1,"status":"refunded"}

$ try -b sam.jar -X POST $B/orders/1/refund

403 {"message":"Order 1 is refunded."}

Shell helpers, then the refund route for a customer and for staff

Gate::allowIf(fn (User $user) => $user->hasRole('staff')) and Gate::denyIf() check a one-off rule inline and throw the same exception. They skip the hooks: through Gate::forUser($ada), that allowIf threw although Ada passes every named gate.