Laravel Sanctum vs Passport 2026: API-Authentifizierung und Interview-Fragen

Vergleich von Laravel Sanctum und Passport für API-Authentifizierung in 2026. Praxisnahe Codebeispiele, SPA-Authentifizierung, OAuth2-Implementierung und Interview-Fragen für Entwickler.

Laravel Sanctum vs Passport 2026: API-Authentifizierung und Interview-Fragen

Laravel Sanctum und Passport bedienen unterschiedliche Anforderungen an die API-Authentifizierung. Die Wahl des falschen Pakets führt entweder zu unnötiger Komplexität oder zu Sicherheitslücken. Dieser Leitfaden analysiert beide Pakete anhand praktischer Codebeispiele und realer Interview-Fragen.

Schnelle Entscheidungshilfe

Sanctum eignet sich für SPA-Authentifizierung und einfache API-Tokens. Passport implementiert vollständiges OAuth2 mit Authorization Codes, Client Credentials und Refresh Tokens. Die meisten Anwendungen benötigen nur Sanctum.

Laravel Sanctum vs Passport: Grundlegende Unterschiede

Sanctum bietet eine leichtgewichtige tokenbasierte Authentifizierung, die für First-Party-Anwendungen konzipiert wurde. Das Paket nutzt Cookie-basierte Session-Authentifizierung für SPAs und Personal Access Tokens für Mobile Apps sowie einfache APIs.

Passport implementiert die vollständige OAuth2-Spezifikation, einschließlich Authorization Servers, Client Credentials Grants und Machine-to-Machine-Authentifizierung. Diese Komplexität ist sinnvoll für Anwendungen, die Drittanbieter-Zugriff autorisieren müssen.

| Merkmal | Sanctum | Passport | |---------|---------|----------| | Hauptanwendungsfall | SPAs, Mobile Apps, Simple APIs | Third-Party OAuth2, Machine-to-Machine | | Token-Typ | Einfache gehashte Tokens | JWT mit OAuth2 Scopes | | Session Auth | Ja (Cookie-basiert) | Nein | | OAuth2 Grants | Keine | Vollständige Spezifikation | | Paketgröße | Minimal | Umfangreich | | Konfiguration | Einfach | Komplex |

Sanctum für SPA-Authentifizierung implementieren

Die SPA-Authentifizierung mit Sanctum basiert auf Laravel-Session-Cookies anstelle von API-Tokens. Frontend und Backend müssen sich dieselbe Top-Level-Domain teilen, damit dies funktioniert.

config/sanctum.phpphp
return [
    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
        '%s%s',
        'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
        env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
    ))),

    'expiration' => null, // Tokens laufen standardmäßig nie ab

    'middleware' => [
        'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
        'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
    ],
];

Die SPA muss den CSRF-Cookie-Endpoint aufrufen, bevor authentifizierte Anfragen gestellt werden. Dadurch wird die Session etabliert und das XSRF-TOKEN-Cookie gesetzt.

javascript
// Frontend: CSRF-Schutz vor dem Login initialisieren
async function initializeAuth() {
    await fetch('/sanctum/csrf-cookie', {
        credentials: 'include'
    });
}

async function login(email, password) {
    await initializeAuth();
    
    const response = await fetch('/api/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-XSRF-TOKEN': getCookie('XSRF-TOKEN'),
            'Accept': 'application/json'
        },
        credentials: 'include',
        body: JSON.stringify({ email, password })
    });
    
    return response.json();
}

Sanctum API-Token-Authentifizierung

Mobile Anwendungen und Drittanbieter-Integrationen verwenden Personal Access Tokens anstelle von Session-Cookies. Sanctum speichert diese Tokens als SHA-256-Hashes in der Datenbank.

app/Http/Controllers/AuthController.phpphp
namespace App\Http\Controllers;

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

class AuthController extends Controller
{
    public function createToken(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)) {
            throw ValidationException::withMessages([
                'email' => ['Die angegebenen Anmeldedaten sind ungültig.'],
            ]);
        }

        // Token mit Fähigkeiten (Scopes)
        $token = $user->createToken(
            $request->device_name,
            ['read', 'write'] // Optionale Fähigkeiten
        );

        return response()->json([
            'token' => $token->plainTextToken,
            'expires_at' => null // In sanctum.php konfigurieren
        ]);
    }

    public function revokeToken(Request $request)
    {
        // Aktuellen Token widerrufen
        $request->user()->currentAccessToken()->delete();

        return response()->json(['message' => 'Token widerrufen']);
    }
}

Routen werden mit der auth:sanctum Middleware geschützt. Token-Fähigkeiten werden mit der tokenCan-Methode überprüft.

routes/api.phpphp
use Illuminate\Support\Facades\Route;

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

    Route::post('/posts', function (Request $request) {
        // Prüfen, ob Token Schreibrechte hat
        if (! $request->user()->tokenCan('write')) {
            abort(403, 'Token hat keine Schreibrechte');
        }

        return Post::create($request->validated());
    });
});

Laravel Passport für OAuth2 einrichten

Passport erfordert eine umfangreichere Einrichtung, bietet aber vollständige OAuth2-Funktionalität. Die Installation erstellt Datenbanktabellen für Clients, Tokens und Refresh Tokens.

bash
composer require laravel/passport
php artisan passport:install

Der passport:install-Befehl generiert Verschlüsselungsschlüssel und erstellt Personal Access sowie Password Grant Clients.

app/Models/User.phpphp
namespace App\Models;

use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens;

    // ...
}

Die Passport-Routen werden im AuthServiceProvider registriert:

app/Providers/AuthServiceProvider.phpphp
namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Passport::tokensExpireIn(now()->addDays(15));
        Passport::refreshTokensExpireIn(now()->addDays(30));
        Passport::personalAccessTokensExpireIn(now()->addMonths(6));
    }
}

OAuth2 Password Grant mit Passport

Der Password Grant ermöglicht es First-Party-Anwendungen, Tokens mit Benutzername und Passwort zu erhalten. Dies wird häufig für Mobile Apps verwendet.

app/Http/Controllers/OAuth/TokenController.phpphp
namespace App\Http\Controllers\OAuth;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use App\Http\Controllers\Controller;

class TokenController extends Controller
{
    public function issueToken(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $response = Http::asForm()->post(config('app.url') . '/oauth/token', [
            'grant_type' => 'password',
            'client_id' => config('passport.password_client_id'),
            'client_secret' => config('passport.password_client_secret'),
            'username' => $request->email,
            'password' => $request->password,
            'scope' => '*',
        ]);

        if ($response->failed()) {
            return response()->json([
                'error' => 'Ungültige Anmeldedaten'
            ], 401);
        }

        return $response->json();
    }
}

Client Credentials Grant für Machine-to-Machine

Der Client Credentials Grant ist ideal für Server-zu-Server-Kommunikation, bei der keine Benutzerinteraktion erforderlich ist.

php
// Middleware für Client Credentials
Route::middleware(['client'])->group(function () {
    Route::get('/api/external/data', function () {
        return response()->json([
            'data' => ExternalData::all()
        ]);
    });
});

Die Client-Anwendung authentifiziert sich mit Client ID und Secret:

php
// Externer Service: Token anfordern
$response = Http::asForm()->post('https://api.example.com/oauth/token', [
    'grant_type' => 'client_credentials',
    'client_id' => 'client-id',
    'client_secret' => 'client-secret',
    'scope' => 'read-data',
]);

$token = $response->json()['access_token'];

// API mit Token aufrufen
$data = Http::withToken($token)
    ->get('https://api.example.com/api/external/data')
    ->json();

Token-Scopes für granulare Berechtigungen

Sowohl Sanctum als auch Passport unterstützen Scopes zur Einschränkung von Token-Berechtigungen. Passport definiert Scopes im AuthServiceProvider:

app/Providers/AuthServiceProvider.phpphp
use Laravel\Passport\Passport;

public function boot(): void
{
    Passport::tokensCan([
        'read-posts' => 'Beiträge lesen',
        'write-posts' => 'Beiträge erstellen und bearbeiten',
        'delete-posts' => 'Beiträge löschen',
        'admin' => 'Voller Administratorzugriff',
    ]);

    Passport::setDefaultScope([
        'read-posts',
    ]);
}

Routen können dann spezifische Scopes erfordern:

routes/api.phpphp
Route::middleware(['auth:api', 'scope:write-posts'])->group(function () {
    Route::post('/posts', [PostController::class, 'store']);
    Route::put('/posts/{post}', [PostController::class, 'update']);
});

Route::middleware(['auth:api', 'scopes:read-posts,write-posts'])->group(function () {
    // Erfordert BEIDE Scopes
    Route::get('/posts/drafts', [PostController::class, 'drafts']);
});

Bereit für deine Laravel-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

Sicherheitsaspekte bei der Token-Authentifizierung

Die sichere Handhabung von Tokens erfordert mehrere Schutzmaßnahmen. Token-Rotation verhindert die langfristige Nutzung kompromittierter Credentials.

app/Http/Controllers/TokenController.phpphp
public function refreshToken(Request $request)
{
    $user = $request->user();
    $currentToken = $user->currentAccessToken();
    
    // Alten Token widerrufen
    $currentToken->delete();
    
    // Neuen Token mit gleichen Fähigkeiten erstellen
    $newToken = $user->createToken(
        $currentToken->name,
        $currentToken->abilities
    );
    
    return response()->json([
        'token' => $newToken->plainTextToken,
        'message' => 'Token erfolgreich erneuert'
    ]);
}

Für erhöhte Sicherheit sollten Token-Ablaufzeiten konfiguriert werden:

config/sanctum.phpphp
return [
    'expiration' => 60 * 24, // 24 Stunden in Minuten
    
    // Abgelaufene Tokens automatisch entfernen
    'prune_after' => 7, // Tage
];

Der Scheduler kann abgelaufene Tokens automatisch bereinigen:

app/Console/Kernel.phpphp
protected function schedule(Schedule $schedule): void
{
    $schedule->command('sanctum:prune-expired --hours=24')->daily();
}

Interview-Fragen zu Laravel API-Authentifizierung

Technische Interviews für Laravel-Entwickler prüfen häufig das Verständnis von Authentifizierungskonzepten. Die folgenden Fragen und Antworten decken die wichtigsten Themen ab.

Frage: Wann sollte Sanctum gegenüber Passport gewählt werden?

Sanctum ist die richtige Wahl für First-Party-Anwendungen: SPAs, die auf derselben Domain wie die API laufen, Mobile Apps, die von demselben Team entwickelt werden, und einfache API-Token-Anforderungen. Passport wird benötigt, wenn OAuth2-Funktionalität erforderlich ist: Drittanbieter-Anwendungen, die Zugriff benötigen, Authorization Code Flow für externe Dienste, Client Credentials für Server-zu-Server-Kommunikation oder Refresh Token Rotation.

Frage: Wie funktioniert die CSRF-Schutzmechanismus bei Sanctum SPA-Authentifizierung?

Bei der SPA-Authentifizierung verwendet Sanctum Laravel-Sessions und Cookies. Der Prozess beginnt mit einem Request an /sanctum/csrf-cookie, der ein XSRF-TOKEN-Cookie setzt. Die SPA liest dieses Cookie und sendet den Wert im X-XSRF-TOKEN-Header bei jeder authentifizierten Anfrage. Laravel validiert diesen Token gegen den Session-gespeicherten Wert. Dies schützt vor Cross-Site Request Forgery, da andere Domains das Cookie nicht lesen können.

Frage: Was sind die Sicherheitsimplikationen von Personal Access Tokens?

Personal Access Tokens funktionieren wie Passwörter mit unbegrenzter Gültigkeit. Sicherheitsmaßnahmen umfassen: begrenzte Scopes für jeden Token, Token-Ablaufzeiten, sichere Speicherung auf Client-Seite, Möglichkeit zum sofortigen Widerruf, Logging aller Token-Nutzung und regelmäßige Token-Rotation.

Frage: Wie implementiert man Rate Limiting für API-Authentifizierung?

Rate Limiting schützt vor Brute-Force-Angriffen und API-Missbrauch:

app/Providers/RouteServiceProvider.phpphp
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;

public function boot(): void
{
    RateLimiter::for('api', function (Request $request) {
        return Limit::perMinute(60)->by(
            $request->user()?->id ?: $request->ip()
        );
    });

    RateLimiter::for('auth', function (Request $request) {
        return Limit::perMinute(5)->by(
            $request->ip()
        );
    });
}

Frage: Wie testet man authentifizierte API-Endpoints?

Laravel bietet die actingAs-Methode für Tests mit Sanctum und Passport:

tests/Feature/ApiTest.phpphp
use App\Models\User;
use Laravel\Sanctum\Sanctum;

public function test_authenticated_user_can_access_profile(): void
{
    $user = User::factory()->create();
    
    Sanctum::actingAs($user, ['read']);
    
    $response = $this->getJson('/api/user');
    
    $response->assertOk()
        ->assertJson(['email' => $user->email]);
}

public function test_token_without_scope_cannot_write(): void
{
    $user = User::factory()->create();
    
    Sanctum::actingAs($user, ['read']); // Kein 'write' Scope
    
    $response = $this->postJson('/api/posts', [
        'title' => 'Test Post'
    ]);
    
    $response->assertForbidden();
}

Multi-Guard-Authentifizierung konfigurieren

Komplexe Anwendungen benötigen möglicherweise mehrere Authentifizierungsmechanismen gleichzeitig. Laravel erlaubt die Definition mehrerer Guards:

config/auth.phpphp
return [
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'sanctum',
            'provider' => 'users',
        ],
        'admin-api' => [
            'driver' => 'passport',
            'provider' => 'admins',
        ],
    ],
    
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ],
    ],
];

Routen können dann spezifische Guards verwenden:

routes/api.phpphp
Route::middleware('auth:api')->group(function () {
    // Sanctum-geschützte Routen für normale Benutzer
});

Route::prefix('admin')->middleware('auth:admin-api')->group(function () {
    // Passport-geschützte Routen für Administratoren
});

Best Practices für Produktionsumgebungen

Die Bereitstellung von API-Authentifizierung in Produktionsumgebungen erfordert zusätzliche Überlegungen. HTTPS ist obligatorisch für alle Token-übertragenden Requests. Environment-Variablen sollten sensible Konfigurationen speichern.

.envphp
SANCTUM_STATEFUL_DOMAINS=app.example.com,api.example.com
SESSION_DOMAIN=.example.com

# Passport
PASSPORT_PRIVATE_KEY="..."
PASSPORT_PUBLIC_KEY="..."

Monitoring und Logging authentifizierungsbezogener Ereignisse hilft bei der Erkennung von Angriffen:

app/Listeners/LogAuthenticationEvent.phpphp
namespace App\Listeners;

use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Log;

class LogAuthenticationEvent
{
    public function handle(Login $event): void
    {
        Log::info('Benutzeranmeldung', [
            'user_id' => $event->user->id,
            'ip' => request()->ip(),
            'user_agent' => request()->userAgent(),
        ]);
    }
}

Laravel-Entwickler, die API-Authentifizierung implementieren, sollten die offiziellen Dokumentationen von Sanctum und Passport gründlich studieren. Die Wahl zwischen beiden Paketen hängt von den spezifischen Anforderungen der Anwendung ab.

Passez à la pratique !

Fazit

Laravel Sanctum und Passport bedienen unterschiedliche Authentifizierungsanforderungen. Sanctum bietet eine einfache, aber sichere Lösung für SPAs und Mobile Apps mit First-Party-Token-Authentifizierung. Passport implementiert vollständiges OAuth2 für Szenarien, die Drittanbieter-Autorisierung oder Machine-to-Machine-Kommunikation erfordern.

Die Wahl sollte auf den tatsächlichen Anforderungen basieren: Sanctum für die meisten Anwendungen, Passport nur wenn OAuth2-Funktionalität unverzichtbar ist. Beide Pakete erfordern sorgfältige Konfiguration von Token-Ablaufzeiten, Scopes und Rate Limiting für produktionsreife Implementierungen.

Entwickler sollten die CSRF-Schutzmechanismen bei SPA-Authentifizierung verstehen, Token-Rotation implementieren und umfassende Tests für alle Authentifizierungspfade schreiben. Diese Kenntnisse sind nicht nur für die tägliche Arbeit relevant, sondern auch ein wichtiger Bestandteil technischer Interviews für Laravel-Positionen.

Teilen

Verwandte Artikel