Controller Middleware

Controller Middleware and Authorization Attributes

Laravel 13 2,157 lets a controller declare middleware with attributes: #[Middleware] on the class (narrowed by only: or except:) or on one method, and #[WithoutMiddleware] to remove route middleware. #[Authorize('ability', 'parameter')] is shorthand for the can middleware and its policy check (The Authorize Attribute).

Attributes on the web ProductControllerPHP
#[Middleware('auth.basic', except: ['index', 'show'])]
class ProductController extends Controller
{
    #[Authorize('update', 'product')]
    public function edit(Product $product): View { /* ... */ }
    #[Authorize('delete', 'product')]     // ProductPolicy: admin only, and stock must be 0
    public function destroy(Product $product): RedirectResponse { /* ... */ }
}
Output
$ R='-u reader@example.com:secret123' A='-u admin@example.com:secret123'
$ H='Sec-Fetch-Site: same-origin'; C="curl -s -o /dev/null -w %{http_code}\n"
$ $C -X POST -H "$H" $B/products; $C $R $B/products/3/edit
401
403
$ $C $A -X DELETE -H "$H" $B/products/2; $C $A -X DELETE -H "$H" $B/products/3
403
302

route:list -v lists auth.basic and Authorize:update,product on products.edit. A guest got 401, a reader 403 from the policy, and the admin 403 for a book still in stock, then 302. Sec-Fetch-Site satisfies CSRF protection (CSRF Protection). The older form, implementing HasMiddleware with a static middleware() method, still works.