{"id":346,"date":"2025-08-27T20:06:26","date_gmt":"2025-08-27T20:06:26","guid":{"rendered":"https:\/\/1v0.net\/blog\/?p=346"},"modified":"2025-08-27T20:06:27","modified_gmt":"2025-08-27T20:06:27","slug":"how-to-build-a-multi-auth-api-with-laravel-sanctum","status":"publish","type":"post","link":"https:\/\/1v0.net\/blog\/how-to-build-a-multi-auth-api-with-laravel-sanctum\/","title":{"rendered":"How to Build a Multi-Auth API with Laravel &amp; Sanctum"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>How to Build a Multi-Auth API with Laravel &amp; Sanctum<\/strong><\/h2>\n\n\n\n<p>Sometimes an app needs different authentication flows for different user types \u2014 for example, <em>customers<\/em> and <em>admins<\/em>. With Laravel Sanctum, you can build a <strong>multi-auth API<\/strong> by defining multiple guards and issuing tokens with different abilities. In this guide, you\u2019ll configure Sanctum for multi-auth, create endpoints for both user roles, and secure them appropriately.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1 &#8211; Configure Guards in auth.php<\/strong><\/h2>\n\n\n\n<p>By default, Laravel has <code>web<\/code> and <code>api<\/code> guards. You can define extra guards for custom roles like <code>admin<\/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\">\/\/ config\/auth.php (snippet)<\/span>\n<span class=\"hljs-string\">'guards'<\/span> =&gt; &#91;\n    <span class=\"hljs-string\">'web'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'session'<\/span>,\n        <span class=\"hljs-string\">'provider'<\/span> =&gt; <span class=\"hljs-string\">'users'<\/span>,\n    ],\n\n    <span class=\"hljs-string\">'api'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'sanctum'<\/span>,\n        <span class=\"hljs-string\">'provider'<\/span> =&gt; <span class=\"hljs-string\">'users'<\/span>,\n    ],\n\n    <span class=\"hljs-string\">'admin'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'sanctum'<\/span>,\n        <span class=\"hljs-string\">'provider'<\/span> =&gt; <span class=\"hljs-string\">'admins'<\/span>,\n    ],\n],\n\n<span class=\"hljs-string\">'providers'<\/span> =&gt; &#91;\n    <span class=\"hljs-string\">'users'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'eloquent'<\/span>,\n        <span class=\"hljs-string\">'model'<\/span> =&gt; App\\Models\\User::class,\n    ],\n    <span class=\"hljs-string\">'admins'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'eloquent'<\/span>,\n        <span class=\"hljs-string\">'model'<\/span> =&gt; App\\Models\\Admin::class,\n    ],\n],<\/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>This configuration adds an <code>admin<\/code> guard that uses Sanctum for authentication. We\u2019ll create an <code>Admin<\/code> model to support it. Each guard maps to its own provider.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2 &#8211; Create Admin Model and Migration<\/strong><\/h2>\n\n\n\n<p>Add a separate <code>admins<\/code> table and model. This keeps admin accounts separate from user accounts.<\/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-comment\">\/\/ database\/migrations\/2025_08_27_000000_create_admins_table.php<\/span>\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Database<\/span>\\<span class=\"hljs-title\">Migrations<\/span>\\<span class=\"hljs-title\">Migration<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Database<\/span>\\<span class=\"hljs-title\">Schema<\/span>\\<span class=\"hljs-title\">Blueprint<\/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\">Schema<\/span>;\n\n<span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Migration<\/span> <\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">up<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">void<\/span> <\/span>{\n        Schema::create(<span class=\"hljs-string\">'admins'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Blueprint $table)<\/span> <\/span>{\n            $table-&gt;id();\n            $table-&gt;string(<span class=\"hljs-string\">'name'<\/span>);\n            $table-&gt;string(<span class=\"hljs-string\">'email'<\/span>)-&gt;unique();\n            $table-&gt;string(<span class=\"hljs-string\">'password'<\/span>);\n            $table-&gt;timestamps();\n        });\n    }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">down<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">void<\/span> <\/span>{\n        Schema::dropIfExists(<span class=\"hljs-string\">'admins'<\/span>);\n    }\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>This migration creates a new <code>admins<\/code> table with unique emails. In practice, you might also add <code>role<\/code> or <code>permissions<\/code> fields for fine-grained access control.<\/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-comment\">\/\/ app\/Models\/Admin.php<\/span>\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Models<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Foundation<\/span>\\<span class=\"hljs-title\">Auth<\/span>\\<span class=\"hljs-title\">User<\/span> <span class=\"hljs-title\">as<\/span> <span class=\"hljs-title\">Authenticatable<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Laravel<\/span>\\<span class=\"hljs-title\">Sanctum<\/span>\\<span class=\"hljs-title\">HasApiTokens<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Admin<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Authenticatable<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">HasApiTokens<\/span>;\n\n    <span class=\"hljs-keyword\">protected<\/span> $fillable = &#91;<span class=\"hljs-string\">'name'<\/span>,<span class=\"hljs-string\">'email'<\/span>,<span class=\"hljs-string\">'password'<\/span>];\n    <span class=\"hljs-keyword\">protected<\/span> $hidden = &#91;<span class=\"hljs-string\">'password'<\/span>];\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>The <code>Admin<\/code> model uses <code>HasApiTokens<\/code> to generate and validate Sanctum tokens, just like the User model.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>3 &#8211; Authentication Endpoints<\/strong><\/h2>\n\n\n\n<p>Create controllers for login\/logout flows for both users and admins. Each will issue tokens tied to the correct guard.<\/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\">\/\/ routes\/api.php<\/span>\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Controllers<\/span>\\<span class=\"hljs-title\">UserAuthController<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Controllers<\/span>\\<span class=\"hljs-title\">AdminAuthController<\/span>;\n\nRoute::post(<span class=\"hljs-string\">'\/user\/login'<\/span>, &#91;UserAuthController::class, <span class=\"hljs-string\">'login'<\/span>]);\nRoute::post(<span class=\"hljs-string\">'\/admin\/login'<\/span>, &#91;AdminAuthController::class, <span class=\"hljs-string\">'login'<\/span>]);\n\nRoute::middleware(<span class=\"hljs-string\">'auth:sanctum'<\/span>)-&gt;group(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\n    Route::post(<span class=\"hljs-string\">'\/user\/logout'<\/span>, &#91;UserAuthController::class, <span class=\"hljs-string\">'logout'<\/span>]);\n    Route::post(<span class=\"hljs-string\">'\/admin\/logout'<\/span>, &#91;AdminAuthController::class, <span class=\"hljs-string\">'logout'<\/span>]);\n});<\/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>This provides separate login endpoints for users and admins. Both use Sanctum, but tokens are tied to their respective models.<\/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\/Controllers\/AdminAuthController.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\">Controllers<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Models<\/span>\\<span class=\"hljs-title\">Admin<\/span>;\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<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\">Hash<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">AdminAuthController<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Controller<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">login<\/span><span class=\"hljs-params\">(Request $request)<\/span>\n    <\/span>{\n        $request-&gt;validate(&#91;\n            <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'required|email'<\/span>,\n            <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'required'<\/span>\n        ]);\n\n        $admin = Admin::where(<span class=\"hljs-string\">'email'<\/span>,$request-&gt;email)-&gt;first();\n\n        <span class=\"hljs-keyword\">if<\/span> (!$admin || !Hash::check($request-&gt;password, $admin-&gt;password)) {\n            <span class=\"hljs-keyword\">return<\/span> response()-&gt;json(&#91;<span class=\"hljs-string\">'message'<\/span> =&gt; <span class=\"hljs-string\">'Invalid credentials'<\/span>], <span class=\"hljs-number\">401<\/span>);\n        }\n\n        $token = $admin-&gt;createToken(<span class=\"hljs-string\">'admin-token'<\/span>,&#91;<span class=\"hljs-string\">'admin'<\/span>])-&gt;plainTextToken;\n\n        <span class=\"hljs-keyword\">return<\/span> response()-&gt;json(&#91;<span class=\"hljs-string\">'token'<\/span> =&gt; $token]);\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">logout<\/span><span class=\"hljs-params\">(Request $request)<\/span>\n    <\/span>{\n        $request-&gt;user()-&gt;currentAccessToken()-&gt;delete();\n        <span class=\"hljs-keyword\">return<\/span> response()-&gt;json(&#91;<span class=\"hljs-string\">'message'<\/span> =&gt; <span class=\"hljs-string\">'Logged out'<\/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>The admin login issues a token with ability <code>admin<\/code>. This lets you enforce role-based access later by checking abilities on tokens. Logout deletes the current token.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>4 &#8211; Securing Routes by Role<\/strong><\/h2>\n\n\n\n<p>You can restrict routes by checking Sanctum token abilities, ensuring only admins can access certain endpoints.<\/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\">\/\/ routes\/api.php (snippet)<\/span>\nRoute::middleware(&#91;<span class=\"hljs-string\">'auth:sanctum'<\/span>,<span class=\"hljs-string\">'ability:admin'<\/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\">'\/admin\/dashboard'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> &#91;<span class=\"hljs-string\">'message'<\/span> =&gt; <span class=\"hljs-string\">'Welcome, Admin!'<\/span>];\n    });\n});<\/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>Here, only tokens created with the <code>admin<\/code> ability can access <code>\/admin\/dashboard<\/code>. Normal user tokens will get a 403 Forbidden response.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>5 &#8211; UI: Simple API Test Page<\/strong><\/h2>\n\n\n\n<p>Here\u2019s a minimal UI to test admin vs user endpoints with tokens.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-comment\">&lt;!-- resources\/views\/api\/multi-auth-test.blade.php --&gt;<\/span>\n@extends('layouts.app')\n\n@section('content')\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Multi-Auth API Tester<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"token\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-control mb-3\"<\/span> <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Paste Bearer Token\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-theme mb-3\"<\/span> <span class=\"hljs-attr\">onclick<\/span>=<span class=\"hljs-string\">\"testUser()\"<\/span>&gt;<\/span>Test User Endpoint<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-danger mb-3\"<\/span> <span class=\"hljs-attr\">onclick<\/span>=<span class=\"hljs-string\">\"testAdmin()\"<\/span>&gt;<\/span>Test Admin Endpoint<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">pre<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"result\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">pre<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/cdn.jsdelivr.net\/npm\/axios\/dist\/axios.min.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">testUser<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> token = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'token'<\/span>).value;\n  axios.get(<span class=\"hljs-string\">'\/api\/posts'<\/span>, { <span class=\"hljs-attr\">headers<\/span>: { <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Bearer <span class=\"hljs-subst\">${token}<\/span>`<\/span> } })\n    .then(<span class=\"hljs-function\"><span class=\"hljs-params\">r<\/span> =&gt;<\/span> <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'result'<\/span>).textContent = <span class=\"hljs-built_in\">JSON<\/span>.stringify(r.data,<span class=\"hljs-literal\">null<\/span>,<span class=\"hljs-number\">2<\/span>))\n    .catch(<span class=\"hljs-function\"><span class=\"hljs-params\">e<\/span> =&gt;<\/span> <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'result'<\/span>).textContent = e);\n}\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">testAdmin<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> token = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'token'<\/span>).value;\n  axios.get(<span class=\"hljs-string\">'\/api\/admin\/dashboard'<\/span>, { <span class=\"hljs-attr\">headers<\/span>: { <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Bearer <span class=\"hljs-subst\">${token}<\/span>`<\/span> } })\n    .then(<span class=\"hljs-function\"><span class=\"hljs-params\">r<\/span> =&gt;<\/span> <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'result'<\/span>).textContent = <span class=\"hljs-built_in\">JSON<\/span>.stringify(r.data,<span class=\"hljs-literal\">null<\/span>,<span class=\"hljs-number\">2<\/span>))\n    .catch(<span class=\"hljs-function\"><span class=\"hljs-params\">e<\/span> =&gt;<\/span> <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'result'<\/span>).textContent = e);\n}\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n@endsection<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This page lets you paste a token and call either a user or an admin endpoint. With the wrong token type, you\u2019ll see an error \u2014 demonstrating multi-auth in action.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>By configuring multiple guards and issuing tokens with Sanctum, you can support different authentication flows for multiple user types. You built an <code>Admin<\/code> model, set up endpoints for login\/logout, secured routes by token abilities, and tested the flow with a simple UI. This approach gives you flexibility while keeping authentication clean and secure.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">What\u2019s Next<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/blog\/using-laravel-passport-for-advanced-api-authentication\">Using Laravel Passport for Advanced API Authentication<\/a><\/li>\n<li><a href=\"\/blog\/how-to-add-jwt-authentication-to-laravel-apis\">How to Add JWT Authentication to Laravel APIs<\/a><\/li>\n<li><a href=\"\/blog\/integrating-laravel-with-third-party-apis-mail-sms-payment\">Integrating Laravel with Third-Party APIs (Mail, SMS, Payment)<\/a><\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>How to Build a Multi-Auth API with Laravel &amp; Sanctum Sometimes an app needs different authentication flows for different user types \u2014 for example, customers and admins. With Laravel Sanctum, you can build a multi-auth API by defining multiple guards and issuing tokens with different abilities. In this guide, you\u2019ll configure Sanctum for multi-auth, create [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":350,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[25,54,22],"class_list":["post-346","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","tag-api","tag-multi-auth","tag-security"],"_links":{"self":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/346","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=346"}],"version-history":[{"count":1,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/346\/revisions"}],"predecessor-version":[{"id":349,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/346\/revisions\/349"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media\/350"}],"wp:attachment":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media?parent=346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/categories?post=346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/tags?post=346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}