{"id":669,"date":"2025-09-06T15:13:52","date_gmt":"2025-09-06T15:13:52","guid":{"rendered":"https:\/\/1v0.net\/blog\/?p=669"},"modified":"2025-09-06T15:13:55","modified_gmt":"2025-09-06T15:13:55","slug":"laravel-12-auth-middleware-history-functionality-and-practical-usage","status":"publish","type":"post","link":"https:\/\/1v0.net\/blog\/laravel-12-auth-middleware-history-functionality-and-practical-usage\/","title":{"rendered":"Laravel 12 Auth Middleware: History, Functionality, and Practical Usage"},"content":{"rendered":"\n<p><strong>Auth middleware<\/strong> is Laravel\u2019s gatekeeper for protected routes. In Laravel 12, the <code>auth<\/code> middleware is an alias to <code>Illuminate\\Auth\\Middleware\\Authenticate<\/code> and it\u2019s configured in <code>bootstrap\/app.php<\/code> (not in <code>app\/Http\/Kernel.php<\/code> like older versions). Below you\u2019ll find: (1) a short history of what moved, (2) what the middleware actually does under the hood, and (3) copy-paste snippets with explanations so your team understands <em>why<\/em> each piece is used.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">1) A Short History: What Changed by Laravel 12?<\/h3>\n\n\n\n<p><strong>Before Laravel 11<\/strong>, you registered global\/group\/alias middleware in <code>app\/Http\/Kernel.php<\/code>. Starting in <strong>Laravel 11<\/strong> and continuing in <strong>Laravel 12<\/strong>, middleware configuration moved to <code>bootstrap\/app.php<\/code> using the <code>-&gt;withMiddleware()<\/code> callback. The default <code>auth<\/code> alias points to the framework\u2019s <code>Illuminate\\Auth\\Middleware\\Authenticate<\/code>. If you need custom behaviour (e.g., redirect URL), create your own class and re-alias it in <code>bootstrap\/app.php<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ bootstrap\/app.php<\/span>\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Foundation<\/span>\\<span class=\"hljs-title\">Application<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Foundation<\/span>\\<span class=\"hljs-title\">Configuration<\/span>\\<span class=\"hljs-title\">Middleware<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Middleware<\/span>\\<span class=\"hljs-title\">EnsureTeamIsActive<\/span>;\n\n<span class=\"hljs-keyword\">return<\/span> Application::configure(basePath: dirname(<span class=\"hljs-keyword\">__DIR__<\/span>))\n    -&gt;withRouting( <span class=\"hljs-comment\">\/* routes\/web.php, routes\/api.php, etc. *\/<\/span> )\n    -&gt;withMiddleware(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Middleware $middleware)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ Define your own aliases (the 'auth' alias already exists by default)<\/span>\n        $middleware-&gt;alias(&#91;\n            <span class=\"hljs-string\">'team.active'<\/span> =&gt; EnsureTeamIsActive::class,\n        ]);\n\n        <span class=\"hljs-comment\">\/\/ You can also prepend\/append to groups like 'web' or 'api':<\/span>\n        <span class=\"hljs-comment\">\/\/ $middleware-&gt;appendToGroup('web', \\App\\Http\\Middleware\\LogWebTiming::class);<\/span>\n        <span class=\"hljs-comment\">\/\/ $middleware-&gt;prepend(\\App\\Http\\Middleware\\TrustHosts::class);<\/span>\n    })\n    -&gt;create();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> This shows the new, Laravel-12-style place where middleware is configured. You\u2019ll come here when adding new middleware aliases or adjusting how groups like <code>web<\/code>\/<code>api<\/code> behave. The <code>auth<\/code> alias is already available, so you usually don\u2019t have to touch it unless you want to override.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">2) What the Auth Middleware Actually Does (Functions &amp; Flow)<\/h3>\n\n\n\n<p>The <code>Authenticate<\/code> middleware\u2019s key methods are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>handle($request, Closure $next, ...$guards)<\/code> \u2014 Entry point. Runs before your controller and decides whether the request can proceed.<\/li>\n\n\n\n<li><code>authenticate($request, array $guards)<\/code> \u2014 Tries each guard (e.g., <code>web<\/code>, <code>sanctum<\/code>). Throws <code>AuthenticationException<\/code> if none authenticates.<\/li>\n\n\n\n<li><code>redirectTo(Request $request)<\/code> \u2014 For browser requests that expect HTML, returns the login URL when unauthenticated. For API\/JSON requests, the middleware typically returns a 401 JSON response instead of redirecting.<\/li>\n<\/ul>\n\n\n\n<p><strong>Why this matters:<\/strong> Understanding these functions explains <em>why<\/em> web visitors get redirected to login while API requests get a 401. It\u2019s the same middleware, but behaviour adapts to the request type and guard.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">3) Core Usage: Protecting Routes (Web)<\/h3>\n\n\n\n<p>Apply the built-in <code>auth<\/code> alias to routes or groups to block unauthenticated access:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Support<\/span>\\<span class=\"hljs-title\">Facades<\/span>\\<span class=\"hljs-title\">Route<\/span>;\n\nRoute::get(<span class=\"hljs-string\">'\/dashboard'<\/span>, fn () =&gt; view(<span class=\"hljs-string\">'dashboard'<\/span>))\n    -&gt;middleware(<span class=\"hljs-string\">'auth'<\/span>); <span class=\"hljs-comment\">\/\/ only logged-in users<\/span>\n\nRoute::middleware(<span class=\"hljs-string\">'auth'<\/span>)-&gt;group(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\n    Route::get(<span class=\"hljs-string\">'\/settings'<\/span>, fn () =&gt; view(<span class=\"hljs-string\">'settings'<\/span>));\n    Route::get(<span class=\"hljs-string\">'\/billing'<\/span>, fn () =&gt; view(<span class=\"hljs-string\">'billing'<\/span>));\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> This is the most common pattern for protecting back-office pages. If a visitor isn\u2019t logged in (no valid <code>web<\/code> session), the middleware triggers a redirect (via <code>redirectTo()<\/code>) to your login route.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">4) APIs: Specify a Guard (Sanctum Example)<\/h3>\n\n\n\n<p>For token-based APIs, specify the <code>sanctum<\/code> guard:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Request<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Support<\/span>\\<span class=\"hljs-title\">Facades<\/span>\\<span class=\"hljs-title\">Route<\/span>;\n\n<span class=\"hljs-comment\">\/\/ Returns the authenticated API user (requires Sanctum token)<\/span>\nRoute::middleware(<span class=\"hljs-string\">'auth:sanctum'<\/span>)-&gt;get(<span class=\"hljs-string\">'\/api\/user'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Request $request)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> $request-&gt;user();\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> Adding <code>:sanctum<\/code> tells <code>Authenticate<\/code> which guard to check. Unauthenticated API calls get a 401 JSON (not a browser redirect), which is the expected behaviour for clients.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">5) Multiple Guards &amp; Order<\/h3>\n\n\n\n<p>You can list several guards; Laravel tries them in order:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Try 'admin' guard first, then fall back to 'web'<\/span>\nRoute::get(<span class=\"hljs-string\">'\/admin'<\/span>, &#91;\\App\\Http\\Controllers\\AdminController::class, <span class=\"hljs-string\">'index'<\/span>])\n    -&gt;middleware(<span class=\"hljs-string\">'auth:admin,web'<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> Useful when admins have a separate guard or provider but you still want to let regular authenticated users in as a fallback. The first successful guard wins.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">6) Overriding the Login Redirect (Customize <code>redirectTo()<\/code>)<\/h3>\n\n\n\n<p>If you want to control where unauthenticated web users are sent, extend the framework middleware and re-alias <code>auth<\/code> to your class:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ app\/Http\/Middleware\/Authenticate.php<\/span>\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Middleware<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Request<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Authenticate<\/span> <span class=\"hljs-keyword\">extends<\/span> \\<span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Auth<\/span>\\<span class=\"hljs-title\">Middleware<\/span>\\<span class=\"hljs-title\">Authenticate<\/span>\n<\/span>{\n    <span class=\"hljs-comment\">\/**\n     * Get the path the user should be redirected to when not authenticated.\n     *\/<\/span>\n    <span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">redirectTo<\/span><span class=\"hljs-params\">(Request $request)<\/span>: ?<span class=\"hljs-title\">string<\/span>\n    <\/span>{\n        <span class=\"hljs-comment\">\/\/ Only redirect for HTML visits; APIs should keep 401 JSON<\/span>\n        <span class=\"hljs-keyword\">return<\/span> $request-&gt;expectsHtml()\n            ? route(<span class=\"hljs-string\">'login'<\/span>) <span class=\"hljs-comment\">\/\/ or 'auth.signin' etc.<\/span>\n            : <span class=\"hljs-keyword\">null<\/span>;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> Overriding <code>redirectTo()<\/code> gives you total control of the browser redirect target without affecting API behaviour (which should remain 401 JSON).<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ bootstrap\/app.php<\/span>\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Foundation<\/span>\\<span class=\"hljs-title\">Application<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Foundation<\/span>\\<span class=\"hljs-title\">Configuration<\/span>\\<span class=\"hljs-title\">Middleware<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Middleware<\/span>\\<span class=\"hljs-title\">Authenticate<\/span>; <span class=\"hljs-comment\">\/\/ our override<\/span>\n\n<span class=\"hljs-keyword\">return<\/span> Application::configure(basePath: dirname(<span class=\"hljs-keyword\">__DIR__<\/span>))\n    -&gt;withRouting( <span class=\"hljs-comment\">\/* ... *\/<\/span> )\n    -&gt;withMiddleware(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Middleware $middleware)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ Re-map the 'auth' alias to use our local Authenticate override<\/span>\n        $middleware-&gt;alias(&#91;\n            <span class=\"hljs-string\">'auth'<\/span> =&gt; Authenticate::class,\n        ]);\n    })\n    -&gt;create();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> The alias mapping above makes <code>-&gt;middleware('auth')<\/code> use your local class everywhere, ensuring consistent redirects across the app.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">7) Route Groups for Dashboards<\/h3>\n\n\n\n<p>Group all authenticated pages together for cleaner files and consistent protection:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">Route<\/span><span class=\"hljs-selector-pseudo\">::middleware(<\/span><span class=\"hljs-selector-attr\">&#91;<span class=\"hljs-string\">'auth'<\/span>]<\/span>)<span class=\"hljs-selector-tag\">-<\/span>&gt;<span class=\"hljs-selector-tag\">group<\/span>(<span class=\"hljs-selector-tag\">function<\/span> () {\n    <span class=\"hljs-attribute\">Route<\/span>::<span class=\"hljs-built_in\">view<\/span>(<span class=\"hljs-string\">'\/app'<\/span>, <span class=\"hljs-string\">'app.index'<\/span>);\n    <span class=\"hljs-attribute\">Route<\/span>::<span class=\"hljs-built_in\">view<\/span>(<span class=\"hljs-string\">'\/profile'<\/span>, <span class=\"hljs-string\">'profile.show'<\/span>);\n    <span class=\"hljs-attribute\">Route<\/span>::<span class=\"hljs-built_in\">get<\/span>(<span class=\"hljs-string\">'\/orders'<\/span>, &#91;\\App\\Http\\Controllers\\OrderController::class, <span class=\"hljs-string\">'index'<\/span>]);\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> Keeps your route files tidy and guarantees that every route in the group requires a session. Easier to reason about and audit.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">8) Testing Authenticated &amp; Guest Flows<\/h3>\n\n\n\n<p>Write tests to confirm redirects for guests and access for authenticated users:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ tests\/Feature\/DashboardTest.php<\/span>\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Tests<\/span>\\<span class=\"hljs-title\">TestCase<\/span>;\n\nit(<span class=\"hljs-string\">'redirects guests to login'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">$this<\/span>-&gt;get(<span class=\"hljs-string\">'\/dashboard'<\/span>)-&gt;assertRedirect(route(<span class=\"hljs-string\">'login'<\/span>));\n});\n\nit(<span class=\"hljs-string\">'allows authenticated users'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\n    $user = \\App\\Models\\User::factory()-&gt;create();\n    <span class=\"hljs-keyword\">$this<\/span>-&gt;actingAs($user)\n         -&gt;get(<span class=\"hljs-string\">'\/dashboard'<\/span>)\n         -&gt;assertOk();\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> These tests lock in expected behaviour: guests are bounced to login, logged-in users get 200 OK. The <code>actingAs()<\/code> helper simulates a valid session for the <code>web<\/code> guard.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">9) Troubleshooting Cheatsheet<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>HTML redirect instead of JSON for API<\/strong>: Ensure the request has <code>Accept: application\/json<\/code> or that the route uses <code>auth:sanctum<\/code>. APIs should return 401 JSON, not redirect.<\/li>\n\n\n\n<li><strong>Wrong redirect URL<\/strong>: Override <code>redirectTo()<\/code> in your local middleware and re-alias <code>auth<\/code> in <code>bootstrap\/app.php<\/code>.<\/li>\n\n\n\n<li><strong>Alias seems ignored<\/strong>: Clear caches after changes.<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">route<\/span><span class=\"hljs-selector-pseudo\">:clear<\/span>\n<span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">config<\/span><span class=\"hljs-selector-pseudo\">:clear<\/span>\n<span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">optimize<\/span><span class=\"hljs-selector-pseudo\">:clear<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Why this is used:<\/strong> Laravel caches can mask recent changes to routing\/middleware. Clearing them ensures your new aliases and redirects take effect immediately.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Key takeaway:<\/strong> In Laravel 12 you still use <code>-&gt;middleware('auth')<\/code> exactly as before. The big change is where middleware is configured (now <code>bootstrap\/app.php<\/code>). When you need custom redirects or guard behaviour, extend the middleware and re-alias it once \u2014 the rest of your app benefits automatically.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Auth middleware is Laravel\u2019s gatekeeper for protected routes. In Laravel 12, the auth middleware is an alias to Illuminate\\Auth\\Middleware\\Authenticate and it\u2019s configured in bootstrap\/app.php (not in app\/Http\/Kernel.php like older versions). Below you\u2019ll find: (1) a short history of what moved, (2) what the middleware actually does under the hood, and (3) copy-paste snippets with explanations [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":673,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[12,13],"class_list":["post-669","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","tag-authentication","tag-login"],"_links":{"self":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/669","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/comments?post=669"}],"version-history":[{"count":1,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/669\/revisions"}],"predecessor-version":[{"id":672,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/669\/revisions\/672"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media\/673"}],"wp:attachment":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media?parent=669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/categories?post=669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/tags?post=669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}