Skip to main content

Command Palette

Search for a command to run...

API-First Architecture with Laravel Sanctum

Published
5 min read
API-First Architecture with Laravel Sanctum
A

Seasoned IT professional with 7+ years of Program & Project Management, Enterprise and Information Architecture, Technical Delivery (IT Manager), IT Service Management, Team Building, Vendor Management, and Technology experience. Solid track record of leading and managing teams and delivering solutions of business value, use of diverse technologies in the fields of Business Intelligence and Enterprise Data Warehouse, Applications, Databases, Web Portals, Infrastructure, Business Products, and various IT solutions.

Look, I'll be honest with you. A few years back, I built this internal tool for a startup. Nothing fancy, just a dashboard to track customer orders. Classic Laravel app, Blade templates, the whole nine yards. Worked great... until the CEO casually mentioned they wanted a mobile app. And maybe a desktop version. Oh, and could we integrate with that third-party system their biggest client uses?

That's when it hit me: I'd backed myself into a corner. My entire app was tightly coupled to server-rendered views. Building separate interfaces meant duplicating logic everywhere. Sound familiar?

This is exactly why API-first architecture exists, and Laravel Sanctum makes it ridiculously easy to pull off. Let me show you how.

What Does "API-First" Actually Mean?

API-first means your backend exposes data through clean API endpoints instead of rendering HTML directly. Your Laravel app becomes a data service that any frontend like React, Vue, mobile apps, even your smart fridge if you're feeling ambitious, can consume.

Think about how Spotify works. Their core service is an API. The web player, desktop app, mobile apps, and even PlayStation integration all hit the same endpoints. One backend, infinite possibilities.

Here's the thing though: APIs need authentication. You can't just let anyone hit your /api/users endpoint and grab sensitive data. That's where Sanctum comes in.

Why Sanctum Over Other Options?

Laravel ships with a few auth options, and honestly, it can feel overwhelming. Here's my take after using them all:

  • Laravel Passport: Full OAuth2 server. Overkill unless you're building "Sign in with YourApp" functionality

  • JWT packages: They work, but you're managing tokens manually and dealing with refresh logic

  • Sanctum: Sweet spot for SPAs and mobile apps. Simple, lightweight, and it just works

Sanctum gives you two authentication methods in one package:

  1. Cookie-based auth for your SPA (think Vue or React running on the same domain)

  2. API tokens for mobile apps or third-party integrations

I use cookie auth for my main web app and tokens for the iOS version. Same Laravel backend, zero headaches.

Setting Up Your First Sanctum API

Let's get practical. Here's how I'd set this up from scratch.

First, install Sanctum (if you're on Laravel 11+, it's already there):

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

Now, protect your API routes. Pop open routes/api.php:

use Illuminate\Support\Facades\Route;

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });

    Route::apiResource('posts', PostController::class);
});

That's it. Seriously. Any route inside that middleware group now requires authentication.

Real-World Example: Building a Task Manager API

Let me walk you through something I built last month. A simple task manager where users can create and share tasks. Here's how the authentication flow works:

Registration endpoint (routes/api.php):

Route::post('/register', function (Request $request) {
    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => Hash::make($request->password)
    ]);

    $token = $user->createToken('mobile-app')->plainTextToken;

    return ['token' => $token, 'user' => $user];
});

When a user registers through my mobile app, they get a token back. The app stores it and includes it in every future request as a Bearer token.

Creating a task (protected route):

Route::post('/tasks', function (Request $request) {
    return $request->user()->tasks()->create([
        'title' => $request->title,
        'completed' => false
    ]);
})->middleware('auth:sanctum');

Notice how $request->user() automatically gives me the authenticated user? That's Sanctum working its magic behind the scenes. The middleware validates the token, finds the user, and injects it into the request.

Here's where Sanctum really shines. If your frontend lives on the same domain (or subdomain) as your Laravel app, you can skip tokens entirely and use cookies.

I recently rebuilt a client portal this way. React frontend on app.example.com, Laravel API on api.example.com. Here's the setup:

  1. Configure your .env:
SANCTUM_STATEFUL_DOMAINS=app.example.com
SESSION_DOMAIN=.example.com
  1. Your React app calls /sanctum/csrf-cookie first, then makes a login request

  2. Laravel returns a session cookie

  3. All subsequent requests include that cookie automatically

The beauty here? Your frontend code looks identical to a traditional form submission, but you get all the benefits of an API architecture. I've seen companies like Basecamp use this pattern. Their web app feels snappy because it's essentially a SPA hitting APIs, but session management is dead simple.

Mobile Apps and Token Management

For mobile apps, tokens are your best bet. Here's my typical setup:

Login flow: App posts credentials to /api/login, gets a token back, stores it securely (Keychain on iOS, Keystore on Android)

Making requests: Include the token in headers:

Authorization: Bearer your-token-here

Token abilities: Sanctum lets you scope permissions:

$token = $user->createToken('mobile', ['tasks:read', 'tasks:write']);

Then check abilities in your routes:

if ($request->user()->tokenCan('tasks:write')) {
    // Allow task creation
}

I used this for a freelance project where clients could view invoices but only admins could edit them. Same token system, different permissions.

Common Challenges I've Face

CORS issues: If your SPA and API are on different domains, configure CORS properly in config/cors.php. Set supports_credentials to true.

Token revocation: Always give users a way to revoke tokens. I add a "Sign out of all devices" button that calls:

$request->user()->tokens()->delete();

Rate limiting: Sanctum doesn't include this by default. Add throttle middleware to prevent abuse:

Route::middleware(['auth:sanctum', 'throttle:60,1'])->group(...)

Wrapping Up

Look, API-first architecture isn't just a fancy buzzword. It's how you future-proof your apps. When that inevitable "can we build an Android version?" request comes (and it will), you'll be ready.

Sanctum makes this transition smooth. It's not perfect for every scenario. if you're building OAuth for third parties, grab Passport instead (We’ll talk about this in detail soon). But for 90% of projects? Sanctum hits the sweet spot between simplicity and power.

Start small. Take one feature from your current Laravel app and expose it as an API. Build a simple mobile view or a React component that consumes it. You'll quickly see why companies like GitHub, Slack, and pretty much every modern SaaS platform work this way.

Your future self (and your future teammates) will thank you.

The Art of Laravel

Part 1 of 12

Laravel isn’t just a framework — it’s a craft. The Art of Laravel captures that spirit, blending technical depth with developer wisdom to help you master queues, authentication, Octane, and more — building apps as elegant as the framework itself.

Up next

Building Microservices with Laravel

So you've been building Laravel apps for a while, and now you're hearing everyone talk about microservices. Maybe your monolithic application is getting too big to manage, or different teams keep stepping on each other's toes during deployments. I've...