Introduction
API security has become one of the most essential parts of modern web development. As applications grow increasingly interconnected—serving mobile apps, single-page applications, and third-party integrations—API endpoints become primary entry points for attackers. A secure API ensures that only authorized users, applications, and services can access or modify data. Laravel Sanctum and middleware offer a complete, flexible, and powerful approach to securing your REST APIs. Sanctum uses lightweight authentication tokens and integrates seamlessly with Laravel’s middleware pipeline, enabling robust access control with almost no complexity.
Sanctum allows your API to authenticate users using personal access tokens, SPA authentication, or mobile tokens—without the complexity of OAuth. Combined with middleware such as auth:sanctum, throttle, role/permission checks, and custom security layers, Sanctum provides a clean yet strong security architecture. This long-form post explores Sanctum in great depth, covering how it works, how to protect private endpoints, how tokens are handled, how middleware enhances security, and how to build a fully secure, scalable API using Laravel’s built-in tools.
Understanding Laravel Sanctum
What Sanctum Is
Sanctum is Laravel’s lightweight API authentication system. It is specifically designed to secure:
- Mobile applications
- Single-page applications (SPAs)
- Third-party API consumers
- Internal systems
- Personal developer tokens
It offers a simpler alternative to OAuth while still providing strong security.
Why Sanctum Is Popular
Simplicity
No need to manage complex OAuth flows.
Flexibility
It works for SPAs, token-based APIs, and mobile apps.
First-Class Laravel Integration
Sanctum uses Laravel’s authentication system and middleware.
Token Abilities
Each token may have specific permissions (abilities).
Low Overhead
Easy to set up and maintain.
Sanctum is the perfect choice for modern API development.
How Sanctum Works
Personal Access Tokens
When a user logs in via your API, you generate a token:
$token = $user->createToken(‘api-token’)->plainTextToken;
This token is then included in the Authorization header of every API request:
Authorization: Bearer your_token_here
Sanctum validates this token automatically.
Token Storage
Tokens are stored in the personal_access_tokens table—encrypted and secure.
Each token belongs to a user and may have optional abilities (permissions).
Token Validation
Sanctum checks:
- The token exists
- The token has not been revoked
- The token matches the hash
- The token has required abilities
If everything checks out, the request proceeds.
Protecting Endpoints Using Middleware
The auth:sanctum Middleware
This middleware ensures that only valid token owners can access private routes.
Example:
Route::middleware(‘auth:sanctum’)->group(function () {
Route::get(‘/user’, function (Request $request) {
return $request->user();
});
});
Any request without a valid Sanctum token is denied.
How the Middleware Works
When the request arrives:
- The middleware extracts the Bearer token
- Sanctum checks token validity
- It verifies the user identity
- It attaches the authenticated user to the request
- Controller logic executes only if token is valid
If token is invalid, a 401 Unauthorized response is returned.
Creating Secure API Authentication
Step 1: Install Sanctum
composer require laravel/sanctum
Step 2: Publish Configuration
php artisan vendor:publish –provider=”Laravel\Sanctum\SanctumServiceProvider”
Step 3: Run Migration
php artisan migrate
Step 4: Add Sanctum Middleware
In api middleware group:
‘auth:sanctum’,
Step 5: Issue Tokens
$user->createToken(‘device_name’)->plainTextToken;
Now your API can authenticate token holders.
Building Secure API Login Flows
Login Endpoint Example
User submits credentials.
If valid, issue token:
public function login(Request $request)
{
$request->validate([
’email’ => ‘required|email’,
‘password’ => ‘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('api-token')->plainTextToken
]);
}
Securing Private Routes
Example of Protected Route Group
Route::middleware(‘auth:sanctum’)->group(function () {
Route::get(‘/dashboard’, function () {
return ‘Private content’;
});
});
Only requests with a valid token may access these endpoints.
What Happens If an Attack Happens Without a Token?
Laravel responds with:
401 Unauthorized
{ “message”: “Unauthenticated.” }
This prevents access before it reaches your controller.
Sanctum Token Abilities (Permissions)
Sanctum allows assigning abilities to tokens.
Example:
$token = $user->createToken(‘token-name’, [‘create’, ‘update’]);
Middleware can check these abilities:
if ($request->user()->tokenCan(‘update’)) {
// Allowed
}
Token abilities offer fine-grained control similar to roles/permissions.
Combining Sanctum With Roles and Permissions
Why Combine Sanctum With Roles?
Sanctum handles authentication.
Roles manage authorization.
This creates a full security system.
Example With Role Check
Inside a controller:
if ($request->user()->role !== ‘admin’) {
return response()->json([‘error’ => ‘Forbidden’], 403);
}
Using Permission Packages
Popular packages like Spatie make it easy to manage roles and permissions.
Example:
$user->hasPermissionTo(‘delete product’);
This, combined with Sanctum, creates a highly secure API.
Rate Limiting APIs
Laravel includes rate limiting middleware out of the box.
Example routes/api.php:
Route::middleware([‘auth:sanctum’, ‘throttle:60,1’])->group(function () {
Route::get(‘/profile’, …);
});
This limits requests to 60 per minute per user/token.
Rate limiting prevents:
- Brute-force attacks
- Abuse
- Performance issues
Middleware Layers for API Security
Middleware executes before your controller handles the request.
It acts as a wall protecting your API.
Common middleware used with Sanctum:
auth:sanctum
Validates tokens.
throttle
Limits request frequency.
verified
Ensures email verification.
can
Checks authorization abilities.
custom middleware
You can write security rules tailored to your application.
Middleware creates a powerful security chain.
Building a Complete Secure API Flow
Step 1: Authenticate User
User logs in → receives a token.
Step 2: Use Token in Requests
Each request includes:
Authorization: Bearer token
Step 3: auth:sanctum Middleware Validates the Token
Only valid tokens allow access.
Step 4: Implement Authorization
Use:
- token abilities
- roles
- policies
- permissions
Step 5: Rate Limit Requests
Throttle middleware protects your API.
Step 6: Log Activity
Activity logs help detect suspicious behavior.
Step 7: Encrypt Sensitive Data
Never expose sensitive info in API responses.
This creates a full security workflow.
Protecting CRUD APIs With Sanctum
CRUD APIs are frequently targeted because they manage critical resources.
Example:
Route::apiResource(‘products’, ProductController::class)->middleware(‘auth:sanctum’);
This ensures that:
- Listing
- Creating
- Updating
- Deleting
can only be done by authenticated tokens.
Example of a Fully Secured Controller
Inside each controller method:
public function update(Request $request, Product $product)
{
if (! $request->user()->tokenCan(‘update’)) {
return response()->json([‘error’ => ‘Forbidden’], 403);
}
$product->update($request->all());
return response()->json($product);
}
Token abilities protect sensitive operations.
Token Revocation
Revoke Token on Logout
$request->user()->currentAccessToken()->delete();
Revoke All Tokens
$request->user()->tokens()->delete();
Revoking tokens is essential when:
- A device is lost
- A session expires
- A user logs out
- A security breach occurs
Sanctum makes this easy.
Expiring Tokens for Security
Tokens remain valid forever unless revoked.
For higher security, manually expire tokens:
$token->forceFill([‘expires_at’ => now()->addDays(7)])->save();
Or delete old tokens via a cron job.
Protecting Public and Private APIs
Public Endpoints
Visible to everyone:
Route::get(‘/products’, …);
Private Endpoints
Require authentication:
Route::get(‘/orders’, …)->middleware(‘auth:sanctum’);
Use middleware to divide access clearly.
Using Policies for Deeper Authorization
Policies ensure that only the resource owner can modify or delete it.
Example:
public function update(User $user, Product $product)
{
return $user->id === $product->owner_id;
}
Use with:
$this->authorize(‘update’, $product);
Policies give you professional-level security.
Custom Security Middleware
You can write your own security rules:
php artisan make:middleware EnsureUserIsActive
Inside handle():
if (! $request->user()->is_active) {
return response()->json([‘error’ => ‘Account inactive’], 403);
}
Apply to routes:
->middleware(‘active’)
Custom middleware helps tailor security for specific business needs.
Common API Attack Types (Sanctum Helps Prevent Them)
Token Theft
Using HTTPS prevents sniffing.
Sanctum validates and revokes tokens.
Brute Force
Throttle middleware blocks repeated attempts.
Unauthorized Access
auth:sanctum ensures only valid tokens enter.
Privilege Escalation
Roles and policies prevent users from performing unauthorized actions.
Data Tampering
Sanctum ties actions to authenticated users.
CSRF Attacks
Sanctum handles SPA authentication securely.
Sanctum is a complete protection layer against common attacks.
Best Practices for Securing APIs with Sanctum and Middleware
Always Use HTTPS
Never send tokens over plain HTTP.
Rotate Tokens Regularly
Delete and reissue tokens periodically.
Limit Token Abilities
Never give a token more permissions than it needs.
Use Policies for Complex Permissions
Organize and centralize authorization logic.
Separate Admin and User Tokens
Admin tokens should have more security checks.
Keep Middleware Lean
Avoid heavy operations inside middleware.
Validate All Input
Sanctum secures access but not data quality.
Monitor Logs
Failed token attempts indicate attacks.
Advanced Security Practices
Device-Based Token Naming
Use meaningful device names:
phone_ipad_2025
office_laptop_chrome
Token Fingerprinting
Compare device/user-agent information with stored metadata.
Automatic Token Revocation
Revoke tokens after suspicious activity.
Limit Number of Tokens per User
Prevent abuse by restricting token count.
Scoped API Keys
Give external developers scoped keys that limit access.
When to Use Sanctum vs Passport
Sanctum is ideal for:
- SPAs
- Mobile apps
- Internal APIs
- Lightweight authentication
Passport is ideal for:
- First-party and third-party OAuth
- Complex external authentication
- Enterprise-level integration
Sanctum is lightweight, fast, and perfect for most modern APIs.
Logging and Monitoring API Activity
Log API Usage
Log every authenticated request.
Store IP Addresses
Track unusual access patterns.
Create an Audit Log
Store:
- User
- Endpoint
- HTTP method
- Timestamp
- Token ID
Monitoring strengthens your security posture.
Example API Workflow Using Sanctum
- User logs in using email/password
- Server issues a personal access token
- User stores token securely on the client
- All API requests include the Bearer token
- auth:sanctum middleware verifies the token
- Role/permission middleware checks authorization
- Controller executes logic
- Response returned
- User logs out → token revoked
Leave a Reply