Laravel 8: Using Fortify in APIs
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# Laravel Fortify in the API World: Moving Beyond Redirection for Token-Based Authentication
As a senior developer working with modern Laravel applications, we often face a common architectural question when moving from traditional web apps to API services: how do we leverage robust authentication frameworks like Fortify when our primary interaction is JSON-based, not HTML-based?
The core issue you've identified is absolutely correct: Laravel Fortify, by design, excels at managing the full user experienceâhandling login forms, session management, and redirection. This behavior is fundamentally incompatible with stateless RESTful API authentication, where the client (like a Vue frontend) expects a simple success or failure JSON response containing an access token, rather than being redirected to a separate home page.
This post will explore how we can use Laravel's powerful authentication scaffolding (which Fortify manages) as the *foundation* for building secure API endpoints, specifically by integrating it seamlessly with Laravel Sanctum for token management.
## The Limitation of Default Fortify Behavior
When you use Fortify alone in a standard web context, it automates the entire flow:
1. User submits credentials.
2. Fortify validates them against the database.
3. If successful, Fortify sets a session and redirects the user (e.g., to `/dashboard`).
For an API, this redirection is noise. An API login should follow the OAuth 2.0 or token-based flow: client sends credentials $\rightarrow$ server returns token. We need to decouple the authentication *logic* from the presentation *layer*.
The `authenticateUsing` function in Fortify customizes *what* happens during the process, but it doesn't fundamentally change Fortify's built-in responsibility of handling session redirects. Therefore, relying solely on Fortify for token issuance is counterproductive.
## The Solution: Fortify as the Foundation, Sanctum as the API Layer
The correct approach in the Laravel ecosystem is to use Fortify (or Laravel Breeze/Jetstream which often utilize Fortify underneath) to handle the **user management** (registration, password hashing, basic verification), and then delegate the actual **API token issuance and validation** to a dedicated package like Laravel Sanctum.
Sanctum is designed exactly for this scenario: providing simple, powerful token authentication suitable for SPAs and mobile applications. It sits atop Laravel's standard authentication mechanisms, giving you full control over the tokens returned in JSON payloads. This separation of concerns keeps your API clean and adheres to REST principles.
### Implementation Steps
To achieve token-based API login without writing boilerplate routes:
1. **Setup Fortify:** Use Fortify to handle all necessary user model interactions (registration, password management).
2. **Implement Sanctum:** Install and configure Laravel Sanctum for token generation.
3. **Custom Login Endpoint:** Create a dedicated route that handles the login logic, validates credentials using the Fortify-managed mechanism, and *then* issues a Sanctum token instead of triggering a redirect.
#### Example: Creating a Token-Based Login
Instead of relying on Fortify's internal web routes for API access, we define our own controller method. This method will use the existing authentication infrastructure to verify the user and then generate the necessary token.
```php
// app/Http/Controllers/Api/AuthController.php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Sanctum\PersonalAccessToken; // Import the necessary model if needed
class AuthController extends Controller
{
public function login(Request $request)
{
// 1. Attempt to authenticate using Laravel's built-in guard (Fortify manages this setup)
if (!Auth::attempt($request->only('email', 'password'))) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$user = Auth::user();
// 2. Generate a new Sanctum token for the authenticated user
$token = $user->createToken('api_token')->plainTextToken;
// 3. Return the token in a JSON response
return response()->json([
'message' => 'Login successful',
'token' => $token,
'user' => $user->only('id', 'name')
], 200);
}
}
```
### Conclusion: API-First Philosophy
By separating the concernsâusing Fortify for ensuring secure user persistence and Sanctum for managing stateless API accessâwe achieve a clean, scalable architecture. We leverage the robust scaffolding provided by Laravel (as seen in resources like [laravelcompany.com](https://laravelcompany.com)) to handle the heavy lifting of authentication, allowing us to focus our custom code purely on defining the API contract. This approach is essential for building modern, decoupled applications that serve both web and mobile clients effectively.