Sanctum of Passport? De keuze hangt niet af van wat je mooi vindt. Het hangt af van wie je API gebruikt: een SPA, een mobiele app of een extern systeem met OAuth2 scopes.
Laravel Sanctum vs Passport — API authenticatie voor e-commerce
De vraag die wij het vaakst krijgen bij nieuwe Laravel API projecten: Sanctum of Passport? Het antwoord is niet welke je leuker vindt. Het antwoord is welke clients jouw API gebruiken en wat zij nodig hebben.
De meeste e-commerce projecten gebruiken Sanctum. Maar er zijn concrete situaties waar Passport de enige juiste keuze is. Dit artikel legt het verschil uit aan de hand van echte use cases.
Wat je leert in dit artikel
- Hoe Sanctum werkt: token authenticatie en SPA authenticatie
- Hoe Passport werkt: OAuth 2.0 volledig geïmplementeerd
- Wanneer Sanctum voldoende is — en wanneer het dat niet is
- Mobiele apps, SPA's en machine-to-machine: welk pakket past waar
- Concrete implementaties voor e-commerce scenarios
Sanctum: lichtgewicht en snel
Sanctum geeft je twee dingen: API token authenticatie voor mobiele apps en server-to-server integraties, en cookie-gebaseerde SPA authenticatie voor Vue of React frontends op hetzelfde domein.
API tokens
Elke gebruiker kan meerdere tokens aanmaken. Elk token kan specifieke scopes (abilities) hebben.
// Token aanmaken bij login
class AuthController extends Controller
{
public function login(Request $request): JsonResponse
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (! Auth::attempt($credentials)) {
return response()->json([
'error' => ['code' => 'INVALID_CREDENTIALS', 'message' => 'E-mailadres of wachtwoord onjuist.'],
], 401);
}
$user = Auth::user();
// Verwijder oude tokens (optioneel — voor mobiele apps gewenst)
$user->tokens()->where('name', 'mobile-app')->delete();
$token = $user->createToken('mobile-app', [
'orders:read',
'orders:create',
'profile:read',
'profile:update',
]);
return response()->json([
'token' => $token->plainTextToken,
'user' => new UserResource($user),
]);
}
}
// Routes beveiligen met Sanctum
Route::middleware('auth:sanctum')->group(function () {
Route::get('/orders', [OrderController::class, 'index']);
// Scope check: gebruiker moet 'orders:create' ability hebben
Route::post('/orders', function (Request $request) {
if (! $request->user()->tokenCan('orders:create')) {
abort(403, 'Token heeft niet de juiste rechten.');
}
// Verwerk order...
});
});
SPA authenticatie met cookies
Voor een Vue of React frontend op hetzelfde domein (of subdomain) gebruikt Sanctum session cookies in plaats van tokens. De browser beheert de cookie automatisch.
// config/sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
// Frontend: eerst CSRF cookie ophalen
await axios.get('/sanctum/csrf-cookie');
// Daarna inloggen
const response = await axios.post('/login', {
email: '[email protected]',
password: 'wachtwoord',
});
// Alle volgende requests zijn automatisch geauthenticeerd via cookie
const orders = await axios.get('/api/v1/orders');
Dit werkt alleen als de frontend en backend op hetzelfde domein of een subdomain draaien. app.jouwshop.nl en api.jouwshop.nl werken. jouwshop.nl en partner-app.nl werken niet.
Passport: volledige OAuth 2.0
Passport implementeert de volledige OAuth 2.0 specificatie. Dat brengt meer mogelijkheden, maar ook meer complexiteit.
De vier OAuth 2.0 flows die Passport ondersteunt:
| Flow | Wanneer gebruiken |
|---|---|
| Authorization Code | Gebruiker autoriseert een externe app |
| Client Credentials | Machine-to-machine zonder gebruiker |
| Password Grant | Eigen apps met directe inlog (verouderd) |
| Implicit Grant | Verouderd, gebruik Authorization Code met PKCE |
Client Credentials voor machine-to-machine
Een ERP systeem dat orders synchroniseert heeft geen gebruikerscontext nodig. Client Credentials flow is hiervoor gemaakt.
// Een API client aanmaken (in Laravel Passport admin of via code)
$client = Passport::client()->create([
'user_id' => null,
'name' => 'Exact Online Koppeling',
'secret' => Str::random(40),
'redirect' => '',
'personal_access_client' => false,
'password_client' => false,
'revoked' => false,
]);
Het ERP systeem vraagt een access token aan:
POST /oauth/token
{
"grant_type": "client_credentials",
"client_id": "3",
"client_secret": "jouw-client-secret",
"scope": "orders:read inventory:write"
}
Response:
{
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1Qi..."
}
// Routes beveiligen voor machine-to-machine clients
Route::middleware(['auth:api', 'scope:orders:read'])->group(function () {
Route::get('/orders', [OrderController::class, 'index']);
});
Authorization Code voor externe koppelingen
Stel dat een marketplace platform namens jouw klanten orders wil plaatsen. De klant moet expliciet toestemming geven. Authorization Code flow regelt dit.
// Passport routes zijn automatisch geregistreerd via Passport::routes()
// Jouw klant wordt doorgestuurd naar:
// GET /oauth/authorize?client_id=5&response_type=code&scope=orders:create&redirect_uri=...
// Na goedkeuring ontvangt de marketplace een authorization code
// Die ruilen ze in voor een access token:
// POST /oauth/token
// { "grant_type": "authorization_code", "code": "...", "redirect_uri": "...", "client_id": "5", "client_secret": "..." }
Dit patroon herken je van "Login met Google" of "Koppel je webshop aan Bol.com". Passport maakt het mogelijk om dit zelf aan te bieden aan partners.
De beslismatrix
| Situatie | Keuze | Reden |
|---|---|---|
| React/Vue SPA zelfde domein | Sanctum (cookies) | Eenvoudiger, veiliger dan tokens in localStorage |
| Mobiele app (iOS/Android) | Sanctum (tokens) | Simpel token management, scopes voor rechten |
| ERP/WMS koppeling server-to-server | Sanctum (tokens) of Passport (Client Credentials) | Sanctum als je geen OAuth nodig hebt |
| Externe partijen koppelen (OAuth2) | Passport | Authorization Code flow vereist Passport |
| Marketplace integraties | Passport | Third-party toegang met gebruikerstoestemming |
| Microservices intern | Sanctum of Passport CC | Afhankelijk van complexiteit |
De vuistregel: begin met Sanctum. Schakel over naar Passport alleen als je een OAuth 2.0 flow nodig hebt die Sanctum niet ondersteunt.
Token levensduur en rotatie
Ongeacht welk pakket je kiest, stel token levensduur in.
// config/sanctum.php — Sanctum token expiratie
'expiration' => 60 * 24 * 30, // 30 dagen in minuten
// Na expiratie moet de client opnieuw inloggen
// Gebruik refresh tokens voor langere sessies zonder opnieuw inloggen
// config/passport.php — Passport token levensduur
use Carbon\CarbonInterval;
'tokens_expire_in' => CarbonInterval::days(15),
'refresh_tokens_expire_in' => CarbonInterval::days(30),
'personal_access_tokens_expire_in' => CarbonInterval::months(6),
Token rotatie bij mobiele apps
Bij mobiele apps roteert een refresh token na gebruik. Zo detecteer je gestolen tokens.
// app/Http/Controllers/Api/AuthController.php
public function refresh(Request $request): JsonResponse
{
$user = $request->user();
// Verwijder huidig token
$request->user()->currentAccessToken()->delete();
// Maak nieuw token aan
$newToken = $user->createToken('mobile-app', $this->getTokenAbilities($user));
return response()->json([
'token' => $newToken->plainTextToken,
]);
}
Veiligheid: wat je nooit mag vergeten
- Sla tokens nooit op in localStorage — Bij XSS aanvallen leest een aanvaller alles uit localStorage. Gebruik cookies (httpOnly, Secure, SameSite) voor SPA's.
- Beperk scopes — Geef tokens minimale rechten. Een readonly koppeling heeft geen write scope nodig.
- Revoke tokens bij uitloggen —
$user->tokens()->delete()voor alle tokens, of$user->currentAccessToken()->delete()voor het huidige token. - Rotate secrets regelmatig — Passport client secrets en Sanctum app keys moeten periodiek roteert worden.
// Correcte logout: altijd het token intrekken
public function logout(Request $request): JsonResponse
{
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Uitgelogd.']);
}
Conclusie
Sanctum is de juiste keuze voor veruit de meeste e-commerce projecten. SPA's op hetzelfde domein, mobiele apps, interne koppelingen — Sanctum handelt dit af met minimale configuratie.
Passport voeg je toe zodra je externe partijen toegang wilt geven via OAuth 2.0. Marketplace koppelingen, partnerplatforms, multi-tenant autorisatie — dat is het domein van Passport.
Sanctum is onderdeel van het Laravel-ecosysteem — zie de Laravel Sanctum documentatie. Voor OAuth 2.0, zie de Laravel Passport documentatie en de OAuth 2.0 specificatie.
Gerelateerde artikelen:- API-beveiliging voor e-commerce integraties — security best practices
- Laravel API design patterns — consistente API's bouwen
- Multi-tenant Laravel voor SaaS — authenticatie per tenant
Bekijk onze Laravel-diensten of neem contact op voor een technisch adviesgesprek.

Geschreven door Ruthger Idema
15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.
Meer over ons team →