Kritim Yantra
Apr 04, 2025
Building modern web applications often requires seamless communication between frontend clients (like SPAs or mobile apps) and a backend API. But how do you securely authenticate these interactions without overcomplicating your codebase? Enter Laravel Sanctum—a lightweight, versatile authentication system designed for simplicity and security. In this blog, we’ll explore how Sanctum works, its core features, and practical examples to implement it in your next project.
Laravel Sanctum is a minimalist authentication package that solves two key challenges:
Whether you’re building a task management API, an e-commerce platform with a Vue.js frontend, or a mobile app, Sanctum streamlines authentication so you can focus on your application’s core logic.
Let’s dive into practical examples!
Start by creating a new Laravel 12 project and installing Sanctum:
laravel new task-manager
cd task-manager
php artisan install:api
This command installs Sanctum and sets up API authentication scaffolding. Next, run migrations to create Sanctum’s token tables:
php artisan migrate
Imagine you’re building a task manager API. Users need to generate tokens to access their tasks from a mobile app. Here’s how to create a token endpoint:
Step 1: Add the HasApiTokens
trait to your User
model:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
Step 2: Create a route to generate tokens in routes/api.php
:
use Illuminate\Http\Request;
Route::post('/tokens/create', function (Request $request) {
$request->validate(['token_name' => 'required']);
$token = $request->user()->createToken(
$request->token_name,
['task:read', 'task:create'] // Abilities
);
return response()->json(['token' => $token->plainTextToken]);
})->middleware('auth:sanctum');
Now, users can send a POST request to /api/tokens/create
with a token_name
to get a token. For example, a mobile app might request a token named "MyTaskApp" with abilities to read and create tasks.
Let’s secure the task endpoints so only tokens with the correct abilities can access them.
Define routes in routes/api.php
:
Route::middleware(['auth:sanctum', 'ability:task:read'])->group(function () {
Route::get('/tasks', [TaskController::class, 'index']);
});
Route::middleware(['auth:sanctum', 'ability:task:create'])->group(function () {
Route::post('/tasks', [TaskController::class, 'store']);
});
A token with task:read
can fetch tasks, while one with task:create
can add new tasks. If a token without task:create
tries to POST to /tasks
, Sanctum blocks it.
Suppose your task manager has a Vue.js SPA hosted at https://tasks.example.com
. Sanctum can authenticate it using sessions instead of tokens.
Step 1: Configure Sanctum’s Stateful Domains
In config/sanctum.php
, allow your SPA’s domain:
'stateful' => [
'tasks.example.com',
],
Step 2: Set Up CORS
Ensure config/cors.php
allows credentials:
'supports_credentials' => true,
Step 3: Authenticate from Vue.js
In your Vue app, first fetch the CSRF cookie:
axios.get('https://api.example.com/sanctum/csrf-cookie').then(() => {
// Now log in
axios.post('https://api.example.com/login', {
email: 'user@example.com',
password: 'password'
}).then(response => {
// Authenticated! Fetch tasks
axios.get('https://api.example.com/api/tasks');
});
});
The SPA now uses session cookies for authentication, with built-in CSRF protection!
For a Flutter mobile app, users log in with email/password to get a token:
Step 1: Create a Token Endpoint
In routes/api.php
:
Route::post('/mobile/login', function (Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return response()->json(['error' => 'Invalid credentials'], 401);
}
return response()->json([
'token' => $user->createToken($request->device_name)->plainTextToken
]);
});
Step 2: Use the Token in the Flutter App
Store the token securely and include it in API requests:
final response = await http.post(
Uri.parse('https://api.example.com/api/tasks'),
headers: {
'Authorization': 'Bearer $yourToken',
'Accept': 'application/json',
},
body: {'title': 'New Task'},
);
Sanctum simplifies testing. Here’s how to test a protected route:
use App\Models\User;
use Laravel\Sanctum\Sanctum;
public function test_user_can_fetch_tasks()
{
Sanctum::actingAs(
User::factory()->create(),
['task:read'] // Grant abilities
);
$response = $this->getJson('/api/tasks');
$response->assertOk();
}
expiration
in config/sanctum.php
for enhanced security.Laravel Sanctum is a game-changer for API authentication. Whether you’re securing a Vue.js app, a mobile application, or a public API, Sanctum offers a flexible, secure, and straightforward solution. By leveraging tokens for external clients and sessions for your SPA, you get the best of both worlds without unnecessary complexity.
Ready to supercharge your authentication workflow? Give Sanctum a try in your next Laravel 12 project! 🚀
No comments yet. Be the first to comment!
Please log in to post a comment:
Continue with Google