web and api groups app/Http/Middleware)
$ php artisan make:middleware EnsureTokenIsValid
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureTokenIsValid
{
public function handle(Request $request, Closure $next): Response
{
if ($request->input('token') !== 'my-secret-token') {
return redirect('home');
}
return $next($request);
}
}
class BeforeMiddleware
{
public function handle(Request $request, Closure $next): Response
{
// Perform action
return $next($request);
}
}
class AfterMiddleware
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
// Perform action
return $response;
}
}
bootstrap/app.php, the 7 default global middlewares are loaded by
->withMiddleware(function (Middleware $middleware) {})
->withMiddleware(function (Middleware $middleware) {
$middleware->append(EnsureTokenIsValid::class); // prepend = add it to the beginning of the list
})
->withMiddleware(function (Middleware $middleware) { // this is the default stack (!)
$middleware->use([
\Illuminate\Foundation\Http\Middleware\InvokeDeferredCallbacks::class,
// \Illuminate\Http\Middleware\TrustHosts::class,
\Illuminate\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Http\Middleware\ValidatePostSize::class,
\Illuminate\Foundation\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
]);
})
| Alias | Middleware |
|---|---|
auth |
Illuminate\Auth\Middleware\Authenticate |
auth.basic |
Illuminate\Auth\Middleware\AuthenticateWithBasicAuth |
auth.session |
Illuminate\Session\Middleware\AuthenticateSession |
cache.headers |
Illuminate\Http\Middleware\SetCacheHeaders |
can |
Illuminate\Auth\Middleware\Authorize |
guest |
Illuminate\Auth\Middleware\RedirectIfAuthenticated |
password.confirm |
Illuminate\Auth\Middleware\RequirePassword |
precognitive |
Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests |
signed |
Illuminate\Routing\Middleware\ValidateSignature |
subscribed |
\Spark\Http\Middleware\VerifyBillableIsSubscribed |
throttle |
Illuminate\Routing\Middleware\ThrottleRequests or Illuminate\Routing\Middleware\ThrottleRequestsWithRedis |
verified |
Illuminate\Auth\Middleware\EnsureEmailIsVerified |
Route::get('admin/profile', 'UserController@showProfile')->middleware('auth');
Route::get('/', function () {
//
})->middleware(['first', 'second']);
or, without aliases:
Route::get('admin/profile', 'UserController@showProfile')->middleware(Authenticate::class);
Route::get('/', function () {
//
})->middleware([First::class, Second::class]);
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first and second Middleware
});
Route::get('user/profile', function () {
// Uses second Middleware
})->withoutMiddleware(['first']);
});
HasMiddleware interfacemiddleware() returns any middlewares that should be applied to the controller's actionsclass TaskController extends Controller implements HasMiddleware
{
public static function middleware(): array
{
return [
'auth',
new Middleware('log', only: ['index']),
new Middleware('subscribed', except: ['store']),
];
}
}
bootstrap/app.php, the 2 default middleware groups web and api are loaded by
->withMiddleware(function (Middleware $middleware) {})
web group applies to any route in routes/web.php
api group applies to any route in routes/api.php
->withMiddleware(function (Middleware $middleware) {
$middleware->appendToGroup('my-group', [ // you can also prepend, replace and remove
First::class,
Second::class,
]);
$middleware->web(append: [ // shorthand for appendToGroup('web', ...
EnsureUserIsSubscribed::class,
]);
})
Route::get('/', 'TaskController@showTask')->middleware('my-group'); // this is just 1 of the options
bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) { // these are the group defaults (!)
$middleware->group('web', [
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
]);
$middleware->group('api', [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
// 'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
]);
})
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string $role): Response
{
if (! $request->user()->hasRole($role)) {
// Redirect...
}
return $next($request);
}
}
,) by adding a : after the middleware name
Route::post('blogposts/create', 'PostController@store')->middleware(EnsureUserHasRole::class.':editor');
Route::post('blogposts/create', 'PostController@store')->middleware('role:editor');