Zum Hauptinhalt springen

Was ist Sanctum

Laravel Sanctum ist ein schlankes Authentifizierungspaket für SPAs (Single Page Applications), mobile Apps und einfache APIs. Ohne OAuth-Komplexität lassen sich pro Benutzer mehrere API-Tokens ausstellen und verwalten. Sanctum löst zwei Probleme:
AuthentifizierungsmodusMechanismusTypische Anwendung
API-Token-AuthentifizierungHeader Authorization: Bearer <token>Mobile Apps, Drittanbieter-Integrationen
SPA-AuthentifizierungSession-Cookie + CSRF-SchutzEigenes Frontend (Vue/React usw.)
Für ein eigenes SPA, das die API aufruft, verwenden Sie die SPA-Authentifizierung. Für mobile Apps oder Dritte, die die API nutzen, die API-Token-Authentifizierung. Sie können auch nur einen der beiden Modi verwenden.

Passport vs. Sanctum

SanctumPassport
KomplexitätEinfachVollständiger OAuth2
Geeignet fürEigenes SPA, mobile AppsOAuth-Provider für externe Apps
Token-TypPersonal Access TokenOAuth2-Access-Token
Wenn Sie als OAuth2-Provider für externe Dienste auftreten müssen, wählen Sie Passport. Für die meisten Anwendungen genügt Sanctum.

Installation und Konfiguration

Installation

Ein einziger Artisan-Befehl richtet Sanctum ein.
php artisan install:api
Dabei geschieht automatisch:
  • Installation des Pakets laravel/sanctum
  • Veröffentlichung der Migration für die Tabelle personal_access_tokens
  • Ausführung der Migration

Trait HasApiTokens hinzufügen

Ergänzen Sie im User-Modell das Trait HasApiTokens.
// app/Models/User.php

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}
Jetzt stehen Methoden wie $user->createToken() und Beziehungen wie $user->tokens zur Verfügung.

API-Token-Authentifizierung

Token-Ablauf

Token ausstellen

Mit createToken() stellen Sie einen Token aus. Über die Eigenschaft plainTextToken erhalten Sie den Klartext-Token. Der Klartext-Token wird nicht in der Datenbank gespeichert – geben Sie ihn dem Benutzer unmittelbar nach der Erstellung zurück.
use Illuminate\Http\Request;

Route::post('/tokens/create', function (Request $request) {
    $token = $request->user()->createToken($request->token_name);

    return ['token' => $token->plainTextToken];
})->middleware('auth');
In der Datenbank wird der Token als SHA-256-Hash abgelegt.

Scopes (Abilities) setzen

Durch Abilities (Scopes) grenzen Sie die Operationen ein, die mit einem Token möglich sind.
// Token mit Scopes ausstellen
$token = $user->createToken('mobile-app', ['server:update', 'server:read']);

return $token->plainTextToken;
Innerhalb der Request-Verarbeitung prüfen Sie die Scopes.
if ($request->user()->tokenCan('server:update')) {
    // Update durchführen
}

if ($request->user()->tokenCant('server:update')) {
    abort(403);
}

Scopes per Middleware prüfen

Registrieren Sie Middleware-Aliase in bootstrap/app.php.
use Laravel\Sanctum\Http\Middleware\CheckAbilities;
use Laravel\Sanctum\Http\Middleware\CheckForAnyAbility;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->alias([
        'abilities' => CheckAbilities::class,  // alle Abilities
        'ability'   => CheckForAnyAbility::class, // mindestens eine Ability
    ]);
})
Und binden Sie sie an Routen.
// Nur Tokens mit check-status UND place-orders
Route::get('/orders', function () {
    // ...
})->middleware(['auth:sanctum', 'abilities:check-status,place-orders']);

// Tokens mit check-status ODER place-orders
Route::get('/orders', function () {
    // ...
})->middleware(['auth:sanctum', 'ability:check-status,place-orders']);

Token-Gültigkeit

Standardmäßig laufen Sanctum-Tokens nie ab. In config/sanctum.php legen Sie unter expiration eine Gültigkeit in Minuten fest.
// config/sanctum.php
'expiration' => 525600, // 365 Tage (Minuten)
Auch pro Token lässt sich eine Gültigkeit angeben.
$token = $user->createToken(
    'token-name',
    ['*'],
    now()->addWeeks(1) // läuft in 1 Woche ab
)->plainTextToken;
Wenn Sie eine Gültigkeit setzen, sollten Sie abgelaufene Tokens regelmäßig entfernen.
use Illuminate\Support\Facades\Schedule;

Schedule::command('sanctum:prune-expired --hours=24')->daily();

Tokens widerrufen

// Alle Tokens entfernen
$user->tokens()->delete();

// Den im aktuellen Request verwendeten Token entfernen
$request->user()->currentAccessToken()->delete();

// Bestimmten Token entfernen
$user->tokens()->where('id', $tokenId)->delete();

SPA-Authentifizierung

Die SPA-Authentifizierung verwendet Session-Cookies und braucht keine Token-Ausstellung. Sie eignet sich, wenn Ihre eigene Frontend-Anwendung (Vue, React, Next.js …) die API aufruft.
Für die SPA-Authentifizierung müssen SPA und API dieselbe Top-Level-Domain haben (unterschiedliche Subdomains sind erlaubt). Zudem sollten Requests die Header Accept: application/json und Referer bzw. Origin enthalten.

Sanctum-Middleware aktivieren

Aktivieren Sie in bootstrap/app.php statefulApi().
->withMiddleware(function (Middleware $middleware): void {
    $middleware->statefulApi();
})

First-Party-Domains konfigurieren

Tragen Sie die SPA-Domains in config/sanctum.php unter stateful ein.
// 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()
))),

CORS konfigurieren

Wenn die API von einer anderen Subdomain aufgerufen wird, benötigen Sie CORS-Einstellungen.
php artisan config:publish cors
Setzen Sie in config/cors.php supports_credentials auf true.
// config/cors.php
'supports_credentials' => true,
Auch das Frontend-axios muss angepasst werden.
// resources/js/bootstrap.js
axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;
Und vergessen Sie nicht die Cookie-Domain.
// config/session.php
'domain' => '.example.com', // führender Punkt

Ablauf der Anmeldung aus dem SPA

1

CSRF-Cookie holen

Vor dem Login den Endpunkt /sanctum/csrf-cookie aufrufen.
await axios.get('/sanctum/csrf-cookie');
2

Login-Request senden

POST-Request an /login.
await axios.post('/login', {
    email: '[email protected]',
    password: 'password',
});
3

Authentifizierte Requests

Nachfolgende Requests werden automatisch über das Session-Cookie authentifiziert.
const response = await axios.get('/api/user');
console.log(response.data); // authentifizierter Benutzer

Authentifizierte Routen schützen

Mit der Middleware auth:sanctum erhalten unauthentifizierte Requests 401 Unauthorized. Beide Modi (Token- und SPA-Auth) werden von dieser Middleware abgedeckt.
use Illuminate\Http\Request;

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

// Routengruppe schützen
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/profile', [ProfileController::class, 'show']);
    Route::put('/profile', [ProfileController::class, 'update']);
    Route::get('/posts', [PostController::class, 'index']);
});

Praxisbeispiel: Login-API mit Token-Rückgabe

Beispiel für die API-Token-Authentifizierung in einer mobilen App.
1

Login-Endpunkt anlegen

// routes/api.php

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

Route::post('/sanctum/token', function (Request $request) {
    $request->validate([
        'email'       => ['required', 'email'],
        'password'    => ['required'],
        'device_name' => ['required', 'string'],
    ]);

    $user = User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages([
            'email' => ['Die angegebenen Anmeldedaten sind ungültig.'],
        ]);
    }

    return response()->json([
        'token' => $user->createToken($request->device_name)->plainTextToken,
    ]);
});
2

Authentifizierte Routen

// routes/api.php

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

    // Aktuellen Token widerrufen (Logout)
    Route::post('/logout', function (Request $request) {
        $request->user()->currentAccessToken()->delete();

        return response()->json(['message' => 'Abgemeldet.']);
    });

    // Von allen Geräten abmelden
    Route::post('/logout/all', function (Request $request) {
        $request->user()->tokens()->delete();

        return response()->json(['message' => 'Von allen Geräten abgemeldet.']);
    });
});
3

Aus dem Client senden

// Login
const { data } = await axios.post('/api/sanctum/token', {
    email: '[email protected]',
    password: 'password',
    device_name: 'My iPhone',
});

const token = data.token;

// Authentifizierter Request
const response = await axios.get('/api/user', {
    headers: {
        Authorization: `Bearer ${token}`,
    },
});

Tests

In Sanctum-Tests authentifizieren Sie mit Sanctum::actingAs() und geben die zu prüfenden Abilities an.
use App\Models\User;
use Laravel\Sanctum\Sanctum;

test('Aufgabenliste abrufen', function () {
    Sanctum::actingAs(
        User::factory()->create(),
        ['view-tasks']
    );

    $response = $this->get('/api/tasks');

    $response->assertOk();
});

test('Zugriff mit Token, der alle Abilities besitzt', function () {
    Sanctum::actingAs(
        User::factory()->create(),
        ['*']
    );

    $response = $this->get('/api/tasks');

    $response->assertOk();
});

Zusammenfassung

# Sanctum installieren und migrieren
php artisan install:api
Trait HasApiTokens im User-Modell:
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}
// Token ausstellen
$token = $user->createToken('token-name')->plainTextToken;

// Mit Scopes ausstellen
$token = $user->createToken('token-name', ['read', 'write'])->plainTextToken;

// Scope prüfen
$user->tokenCan('read');   // true/false
$user->tokenCant('write'); // true/false

// Tokens widerrufen
$user->tokens()->delete();                        // alle
$request->user()->currentAccessToken()->delete(); // aktueller Token
$user->tokens()->where('id', $id)->delete();      // bestimmter Token
  • API-Token-Authentifizierung: für Clients ohne Session – mobile Apps, Drittanbieter, CLI-Tools.
  • SPA-Authentifizierung: für ein eigenes SPA (Vue/React/Next.js) auf derselben Domain/Subdomain. Sicherer und ohne Token-Verwaltung.
Zuletzt geändert am 13. Juli 2026