15%

15% auf alle Hosting-Dienste sparen

Teste deine Fähigkeiten und erhalte Rabatt auf jeden Hosting-Plan

Benutze den Code:

Skills
Anfangen
08.10.2024

Erstellen einer sicheren Laravel API mit JWT-Authentifizierung

JWT (JSON Web Token)-Authentifizierung in Laravel bietet einen zustandslosen, kryptografisch signierten Mechanismus zur Verifizierung von API-Nutzern ohne serverseitige Sitzungsspeicherung. Ein JWT kodiert eine Nutzlast — typischerweise Benutzeridentität und Claims — in einen kompakten, URL-sicheren String, der mit einem geheimen Schlüssel oder RSA-Schlüssel signiert wird, sodass jeder Dienst, der den Verifizierungsschlüssel besitzt, das Token unabhängig validieren kann.

Dieser Leitfaden behandelt die vollständige Implementierung der JWT-Authentifizierung in einer Laravel-API mit dem `tymon/jwt-auth`-Paket, einschließlich Einrichtung, Modellkonfiguration, Controller-Logik, Routenschutz, Token-Refresh-Strategie und Produktionshärtung. Jeder Schritt enthält technischen Kontext, der über oberflächliche Tutorials hinausgeht.

Voraussetzungen und Umgebungsannahmen

Bestätigen Sie vor dem Start Folgendes:

  • PHP 8.1 oder höher (PHP 8.2 empfohlen für Laravel 11)
  • Laravel 10 oder 11 über Composer installiert
  • Composer 2.x
  • MySQL 8.0, PostgreSQL 15 oder eine beliebige PDO-kompatible Datenbank
  • Eine konfigurierte `.env`-Datei mit gültigen `DB_*`-Zugangsdaten
  • Grundlegende Kenntnisse des Laravel-Service-Containers, der Middleware und des Eloquent ORM

Wenn Sie diese API in einer Produktionsumgebung bereitstellen, bietet ein VPS Hosting-Plan mit vollem Root-Zugriff die nötige Kontrolle, um PHP-FPM zu konfigurieren, Umgebungsvariablen sicher zu verwalten und Dateiberechtigungen korrekt zu setzen — alles entscheidend für die JWT-Secret-Verwaltung.

Schritt 1: Ein neues Laravel-Projekt erstellen

“`bash

composer create-project laravel/laravel laravel-jwt-api

cd laravel-jwt-api

“`

Überprüfen Sie die Installation:

“`bash

php artisan –version

“`

Setzen Sie Ihren Anwendungsschlüssel, falls er nicht automatisch generiert wurde:

“`bash

php artisan key:generate

“`

Der `APP_KEY` in `.env` ist vom JWT-Secret getrennt. Beide sind erforderlich und dienen unterschiedlichen kryptografischen Zwecken — `APP_KEY` schützt verschlüsselte Cookies und Sitzungsdaten, während `JWT_SECRET` Token signiert.

Schritt 2: Das JWT-Authentifizierungspaket installieren

Das `tymon/jwt-auth`-Paket ist der De-facto-Standard für JWT in Laravel. Installieren Sie es:

“`bash

composer require tymon/jwt-auth

“`

Veröffentlichen Sie die Paketkonfiguration:

“`bash

php artisan vendor:publish –provider="TymonJWTAuthProvidersLaravelServiceProvider"

“`

Dies erstellt `config/jwt.php`, das Token-TTL, Refresh-TTL, Algorithmus, Blacklist-Verhalten und erforderliche Claims steuert. Überprüfen Sie diese Datei sorgfältig — die Standardwerte sind für die Entwicklung angemessen, müssen aber für die Produktion angepasst werden.

Wichtige Konfigurationsparameter in `config/jwt.php`:

ParameterStandardProduktionsempfehlung
`ttl`60 Minuten15–30 Minuten
`refresh_ttl`20160 Minuten (2 Wochen)1440–10080 Minuten
`algo``HS256``RS256` für verteilte Systeme
`blacklist_enabled``true`Muss `true` sein
`blacklist_grace_period`0 Sekunden10–30 Sekunden für gleichzeitige Anfragen
`required_claims``['iss','iat','exp','nbf','sub','jti']`Alle behalten; `aud` für Multi-Tenant-APIs hinzufügen

Schritt 3: Den JWT-Secret-Schlüssel generieren

“`bash

php artisan jwt:secret

“`

Dies fügt `JWT_SECRET` zu Ihrer `.env`-Datei hinzu. Dieser Wert wird als HMAC-SHA256-Signierungsschlüssel für alle Token verwendet, wenn der Standard-`HS256`-Algorithmus genutzt wird.

Kritische Sicherheitshinweise:

  • Übertragen Sie `.env` niemals in die Versionskontrolle. Fügen Sie es sofort zu `.gitignore` hinzu.
  • Injizieren Sie in einer gemeinsamen Deployment-Pipeline `JWT_SECRET` als Umgebungsvariable über Ihr CI/CD-System, anstatt es in einer Datei zu speichern.
  • Wenn Sie das Secret rotieren, werden alle vorhandenen Token sofort ungültig. Planen Sie Rotationsfenster entsprechend und kommunizieren Sie diese an API-Nutzer.
  • Für Microservice-Architekturen, bei denen mehrere Dienste Token verifizieren müssen, wechseln Sie zu `RS256`. Generieren Sie ein RSA-Schlüsselpaar, speichern Sie den privaten Schlüssel im Auth-Dienst und verteilen Sie nur den öffentlichen Schlüssel an verbrauchende Dienste.

Schritt 4: Den Authentifizierungs-Guard konfigurieren

Öffnen Sie `config/auth.php` und aktualisieren Sie die Abschnitte für Standardwerte und Guards:

“`php

'defaults' => [

'guard' => 'api',

'passwords' => 'users',

],

'guards' => [

'web' => [

'driver' => 'session',

'provider' => 'users',

],

'api' => [

'driver' => 'jwt',

'provider' => 'users',

],

],

“`

Dies weist Laravels Authentifizierungssystem an, den JWT-Treiber zu verwenden, wenn der `api`-Guard aufgelöst wird. Die `auth:api`-Middleware delegiert die Token-Validierung nun an `tymon/jwt-auth` anstatt an Laravel Passport oder den Standard-Token-Treiber.

Entfernen Sie den `web`-Guard nicht. Viele interne Laravel-Komponenten sind davon abhängig, und das Entfernen verursacht unerwartete Fehler in Konsolenbefehlen und Queue-Workern, die mit dem Authentifizierungssystem interagieren.

Schritt 5: Das User-Modell und die Migration erstellen

Wenn das Standard-`User`-Modell und die Migration bereits vorhanden sind (was bei einer frischen Laravel-Installation der Fall ist), können Sie diese direkt ändern. Falls Sie von Grund auf neu beginnen:

“`bash

php artisan make:model User -m

“`

Öffnen Sie die Migrationsdatei in `database/migrations/` und definieren Sie das Schema:

“`php

public function up(): void

{

Schema::create('users', function (Blueprint $table) {

$table->id();

$table->string('name');

$table->string('email')->unique();

$table->timestamp('email_verified_at')->nullable();

$table->string('password');

$table->rememberToken();

$table->timestamps();

});

}

“`

Führen Sie die Migration aus:

“`bash

php artisan migrate

“`

Produktionshinweis: Führen Sie Migrationen in Produktionsumgebungen, in denen `APP_ENV=production` gilt, immer mit dem `–force`-Flag aus, da Laravel sonst zur Bestätigung auffordert:

“`bash

php artisan migrate –force

“`

Schritt 6: Das JWTSubject-Interface im User-Modell implementieren

Das `tymon/jwt-auth`-Paket erfordert, dass Ihr authentifizierbares Modell den `JWTSubject`-Vertrag implementiert. Öffnen Sie `app/Models/User.php`:

“`php

<?php

namespace AppModels;

use IlluminateDatabaseEloquentFactoriesHasFactory;

use IlluminateFoundationAuthUser as Authenticatable;

use IlluminateNotificationsNotifiable;

use TymonJWTAuthContractsJWTSubject;

class User extends Authenticatable implements JWTSubject

{

use HasFactory, Notifiable;

protected $fillable = [

'name',

'email',

'password',

];

protected $hidden = [

'password',

'remember_token',

];

protected $casts = [

'email_verified_at' => 'datetime',

'password' => 'hashed',

];

/**

  • Get the identifier that will be stored in the JWT subject claim.

*/

public function getJWTIdentifier(): mixed

{

return $this->getKey();

}

/**

  • Return a key-value array of arbitrary claims to add to the JWT payload.

*/

public function getJWTCustomClaims(): array

{

return [];

}

}

“`

Zu benutzerdefinierten Claims: Die `getJWTCustomClaims()`-Methode ist der Ort, an dem Sie anwendungsspezifische Daten direkt in die Token-Nutzlast einbetten. Häufige Anwendungsfälle umfassen das Einbetten von `role`, `tenant_id` oder `permissions`, damit nachgelagerte Dienste Autorisierungsentscheidungen ohne Datenbankabfrage treffen können. Seien Sie bewusst darüber, was Sie einbetten — jeder Claim erhöht die Token-Größe und ist für jeden lesbar, der die Nutzlast base64-dekodiert. Betten Sie niemals sensible Daten wie Passwörter oder personenbezogene Daten ein.

Schritt 7: Den Authentifizierungs-Controller erstellen

“`bash

php artisan make:controller AuthController

“`

Befüllen Sie `app/Http/Controllers/AuthController.php` mit vollständiger Authentifizierungslogik:

“`php

<?php

namespace AppHttpControllers;

use AppModelsUser;

use IlluminateHttpJsonResponse;

use IlluminateHttpRequest;

use IlluminateSupportFacadesAuth;

use IlluminateSupportFacadesHash;

use IlluminateValidationValidationException;

use TymonJWTAuthExceptionsJWTException;

use TymonJWTAuthFacadesJWTAuth;

class AuthController extends Controller

{

/**

  • Register a new user and return a JWT.

*/

public function register(Request $request): JsonResponse

{

$validated = $request->validate([

'name' => 'required|string|max:255',

'email' => 'required|string|email|max:255|unique:users',

'password' => 'required|string|min:8|confirmed',

]);

$user = User::create([

'name' => $validated['name'],

'email' => $validated['email'],

'password' => Hash::make($validated['password']),

]);

$token = JWTAuth::fromUser($user);

return response()->json([

'token' => $token,

'token_type' => 'bearer',

'expires_in' => auth('api')->factory()->getTTL() * 60,

], 201);

}

/**

  • Authenticate a user and return a JWT.

*/

public function login(Request $request): JsonResponse

{

$credentials = $request->validate([

'email' => 'required|string|email',

'password' => 'required|string',

]);

if (!$token = Auth::guard('api')->attempt($credentials)) {

return response()->json(['error' => 'Invalid credentials'], 401);

}

return $this->respondWithToken($token);

}

/**

  • Invalidate the current token (logout).

*/

public function logout(): JsonResponse

{

try {

Auth::guard('api')->logout();

} catch (JWTException $e) {

return response()->json(['error' => 'Failed to invalidate token'], 500);

}

return response()->json(['message' => 'Successfully logged out']);

}

/**

  • Refresh the current token.

*/

public function refresh(): JsonResponse

{

try {

$token = Auth::guard('api')->refresh();

} catch (JWTException $e) {

return response()->json(['error' => 'Token cannot be refreshed'], 401);

}

return $this->respondWithToken($token);

}

/**

  • Return the authenticated user's profile.

*/

public function me(): JsonResponse

{

return response()->json(Auth::guard('api')->user());

}

/**

  • Format the token response consistently.

*/

protected function respondWithToken(string $token): JsonResponse

{

return response()->json([

'token' => $token,

'token_type' => 'bearer',

'expires_in' => auth('api')->factory()->getTTL() * 60,

]);

}

}

“`

Warum die explizite Guard-Angabe wichtig ist: Der Aufruf von `Auth::attempt()` ohne Angabe des Guards fällt auf den Standard-Guard zurück. Wenn Sie den Standard auf `api` geändert haben, funktioniert dies — ist aber fehleranfällig. Rufen Sie immer explizit `Auth::guard('api')->attempt()` auf, um subtile Fehler zu vermeiden, wenn der Standard-Guard beim Refactoring geändert wird.

Schritt 8: API-Routen definieren

Öffnen Sie `routes/api.php` und definieren Sie die Authentifizierungs- und geschützten Routen:

“`php

<?php

use AppHttpControllersAuthController;

use IlluminateSupportFacadesRoute;

// Public authentication routes

Route::prefix('auth')->group(function () {

Route::post('register', [AuthController::class, 'register']);

Route::post('login', [AuthController::class, 'login']);

});

// Protected routes — require a valid JWT

Route::middleware('auth:api')->prefix('auth')->group(function () {

Route::post('logout', [AuthController::class, 'logout']);

Route::post('refresh', [AuthController::class, 'refresh']);

Route::get('me', [AuthController::class, 'me']);

});

// Example protected resource routes

Route::middleware('auth:api')->group(function () {

Route::apiResource('posts', AppHttpControllersPostController::class);

});

“`

Routen-Präfix-Strategie: Das Gruppieren von Auth-Endpunkten unter `/api/auth/` ist eine weit verbreitete Konvention, die die API-Dokumentation übersichtlicher macht und Rate-Limiting-Regeln vereinfacht — Sie können strengeres Throttling auf `/api/auth/login` unabhängig von Ressourcen-Endpunkten anwenden.

Schritt 9: Routen schützen und Middleware-Fehler behandeln

Laravels `auth:api`-Middleware gibt eine `401 Unauthenticated`-Antwort zurück, wenn ein Token fehlt, abgelaufen oder ungültig ist. Um stattdessen eine konsistente JSON-Antwort zurückzugeben anstatt einer HTML-Weiterleitung, überschreiben Sie die `unauthenticated`-Methode in `app/Exceptions/Handler.php`:

“`php

use IlluminateAuthAuthenticationException;

use IlluminateHttpRequest;

protected function unauthenticated($request, AuthenticationException $exception)

{

if ($request->expectsJson() || $request->is('api/*')) {

return response()->json(['error' => 'Unauthenticated'], 401);

}

return redirect()->guest(route('login'));

}

“`

Ohne diese Überschreibung erhalten API-Clients eine HTML-302-Weiterleitung zu einer Login-Seite, die in einer reinen API-Anwendung nicht existiert — eine häufige Verwirrungsquelle bei Integrationstests.

Schritt 10: Token-Refresh-Strategie und Blacklisting

Die zustandslose Natur von JWT erzeugt eine Spannung: Token sind eigenständig und bis zum Ablauf gültig, aber Sie benötigen eine Möglichkeit, sie beim Abmelden zu widerrufen. Das `tymon/jwt-auth`-Paket löst dies mit einer Token-Blacklist, die durch den Laravel-Cache-Treiber unterstützt wird.

Wie die Blacklist funktioniert:

  1. Beim Abmelden wird der `jti`-Claim (JWT-ID) des Tokens mit einer TTL, die der verbleibenden Lebensdauer des Tokens entspricht, im Cache gespeichert.
  2. Bei jeder authentifizierten Anfrage prüft die Middleware die Blacklist, bevor das Token akzeptiert wird.
  3. Die `blacklist_grace_period`-Einstellung erlaubt ein kurzes Zeitfenster, in dem ein Token, das gerade aktualisiert wird, noch verwendet werden kann, um Race Conditions bei Clients zu verhindern, die gleichzeitige Anfragen stellen.

Stellen Sie sicher, dass Ihr Cache-Treiber dies unterstützt. Der Standard-`file`-Treiber funktioniert für Einzelserver-Deployments. Für horizontal skalierte APIs, die auf mehreren Knoten laufen — üblich bei der Verwendung von Dedicated Servers in einer lastverteilten Konfiguration — wechseln Sie zu Redis oder Memcached:

“`env

CACHE_DRIVER=redis

REDIS_HOST=127.0.0.1

REDIS_PORT=6379

“`

Token-Refresh-Ablauf:

“`

Client API Server

— POST /api/auth/refresh ——>
Authorization: Bearer <old>
— Validate old token
— Blacklist old token's jti
— Issue new token
<– 200 { token: <new> } ——–

“`

Das alte Token wird beim Refresh sofort auf die Blacklist gesetzt. Clients müssen das neue Token speichern und das alte verwerfen. Implementieren Sie dies als Axios-Interceptor oder Äquivalent in Ihrem Frontend, um den Token-Refresh transparent zu handhaben.

Schritt 11: Die API testen

Verwenden Sie `curl` oder Postman, um jeden Endpunkt zu überprüfen.

Einen Benutzer registrieren:

“`bash

curl -X POST https://your-domain.com/api/auth/register

-H "Content-Type: application/json"

-d '{

"name": "Jane Smith",

"email": "jane@example.com",

"password": "SecurePass123!",

"password_confirmation": "SecurePass123!"

}'

“`

Erwartete Antwort (`201 Created`):

“`json

{

"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…",

"token_type": "bearer",

"expires_in": 3600

}

“`

Anmelden:

“`bash

curl -X POST https://your-domain.com/api/auth/login

-H "Content-Type: application/json"

-d '{"email": "jane@example.com", "password": "SecurePass123!"}'

“`

Auf eine geschützte Route zugreifen:

“`bash

curl -X GET https://your-domain.com/api/auth/me

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

Das Token aktualisieren:

“`bash

curl -X POST https://your-domain.com/api/auth/refresh

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

Abmelden:

“`bash

curl -X POST https://your-domain.com/api/auth/logout

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

JWT vs. Session vs. Laravel Sanctum vs. Passport

Um zu verstehen, wann JWT die richtige Wahl ist, muss es mit den im Laravel-Ökosystem verfügbaren Alternativen verglichen werden.

KriteriumJWT (`tymon/jwt-auth`)Laravel SanctumLaravel PassportSitzungsbasiert
**Zustandsbehaftung**ZustandslosZustandslos (SPA-Token) / Zustandsbehaftet (Cookies)Zustandsbehaftet (DB-Token)Zustandsbehaftet
**Token-Speicherung**ClientseitigClientseitig oder CookieDatenbankServerseitige Sitzung
**Widerruf**Blacklist (Cache)Sofort (DB-Löschung)Sofort (DB-Löschung)Sofort
**Skalierbarkeit**Ausgezeichnet (keine DB pro Anfrage)GutModerat (DB-Abfrage pro Anfrage)Schlecht (Sitzungssynchronisierung erforderlich)
**OAuth2-Unterstützung**NeinNeinJa (vollständiger OAuth2-Server)Nein
**Komplexität**MittelNiedrigHochNiedrig
**Am besten geeignet für**Zustandslose APIs, MicroservicesSPAs, mobile AppsDrittanbieter-OAuth-ClientsTraditionelle Web-Apps
**Token-Introspektion**Nutzlast clientseitig dekodierenErfordert API-AufrufErfordert API-AufrufN/A

Wann JWT gegenüber Sanctum bevorzugt werden sollte: Wenn Ihre API von Drittanbieter-Clients, mobilen Apps oder Microservices genutzt wird, die kein Sitzungs-Cookie oder keine Datenbankverbindung mit Ihrer Laravel-App teilen können, ist die eigenständige Natur von JWT ein erheblicher Vorteil. Wenn Sie eine First-Party-SPA auf derselben Domain erstellen, ist Sanctum mit Cookie-basierter Authentifizierung einfacher und vermeidet Token-Speicher-Sicherheitsbedenken vollständig.

Produktionssicherheitshärtung

Eine funktionierende JWT-Implementierung ist standardmäßig keine sichere. Wenden Sie diese Härtungsmaßnahmen an, bevor Sie live gehen:

1. HTTPS bedingungslos erzwingen

JWT-Token, die über HTTP übertragen werden, sind trivial abfangbar. Erzwingen Sie TLS auf Web-Server-Ebene und leiten Sie den gesamten HTTP-Verkehr um. Kombinieren Sie dies mit einem SSL-Zertifikat, um verschlüsselten Transport für jede API-Anfrage sicherzustellen.

2. Aggressive Token-TTLs setzen

Kurzlebige Access-Token (15–30 Minuten) kombiniert mit längerlebigen Refresh-Token (7–14 Tage) begrenzen den Schaden eines gestohlenen Tokens. Aktualisieren Sie `config/jwt.php`:

“`php

'ttl' => 15,

'refresh_ttl' => 10080,

“`

3. Rate-Limiting auf Authentifizierungsendpunkte anwenden

Laravels integrierte Throttle-Middleware verhindert Brute-Force-Angriffe:

“`php

Route::middleware(['throttle:10,1'])->group(function () {

Route::post('auth/login', [AuthController::class, 'login']);

Route::post('auth/register', [AuthController::class, 'register']);

});

“`

Dies begrenzt jede IP auf 10 Anfragen pro Minute bei Auth-Endpunkten.

4. Den `aud`-Claim für Multi-Tenant-APIs validieren

Wenn Ihre API mehrere Client-Anwendungen bedient, betten Sie einen `audience`-Claim ein und validieren Sie ihn, um die Wiederverwendung von Token über Dienste hinweg zu verhindern:

“`php

// In getJWTCustomClaims()

return [

'aud' => config('app.jwt_audience'),

];

“`

5. Das JWT_SECRET auf OS-Ebene schützen

Setzen Sie restriktive Dateiberechtigungen für `.env`:

“`bash

chmod 640 .env

chown www-data:www-data .env

“`

Auf einem ordnungsgemäß konfigurierten VPS mit cPanel können Sie Dateieigentümerschaft und -berechtigungen über den Dateimanager oder SSH verwalten, ohne das Risiko, Secrets anderen Benutzern auf dem System preiszugeben.

6. Authentifizierungsereignisse protokollieren

Integrieren Sie Laravels Ereignissystem, um fehlgeschlagene Anmeldeversuche, Token-Aktualisierungen und Abmeldungen in einem zentralisierten Protokollierungsdienst zu erfassen. Dies ist für die Anomalieerkennung unerlässlich.

Rollenbasierte Zugriffskontrolle hinzufügen

Benutzerdefinierte Claims machen es einfach, Rollen direkt in das Token einzubetten:

“`php

// In User model

public function getJWTCustomClaims(): array

{

return [

'role' => $this->role, // e.g., 'admin', 'editor', 'viewer'

];

}

“`

Erstellen Sie eine Middleware zur Durchsetzung von Rollenanforderungen:

“`php

<?php

namespace AppHttpMiddleware;

use Closure;

use IlluminateHttpRequest;

use TymonJWTAuthFacadesJWTAuth;

class RoleMiddleware

{

public function handle(Request $request, Closure $next, string $role): mixed

{

$payload = JWTAuth::parseToken()->getPayload();

if ($payload->get('role') !== $role) {

return response()->json(['error' => 'Forbidden'], 403);

}

return $next($request);

}

}

“`

Registrieren Sie sie in `app/Http/Kernel.php` (Laravel 10) oder `bootstrap/app.php` (Laravel 11) und wenden Sie sie auf Routen an:

“`php

Route::middleware(['auth:api', 'role:admin'])->group(function () {

Route::apiResource('admin/users', AdminUserController::class);

});

“`

Vorbehalt: Im Token eingebettete Rollendaten sind nur so aktuell wie das Token selbst. Wenn sich die Rolle eines Benutzers ändert, gewährt das alte Token weiterhin die alte Rolle, bis es abläuft oder aktualisiert wird. Bei sicherheitskritischen Rollenänderungen (z. B. sofortiger Entzug von Admin-Rechten) kombinieren Sie Token-Blacklisting mit einer kurzen TTL oder führen Sie in der Middleware neben der Claim-Prüfung eine Datenbankrollenprüfung durch.

Deployment-Überlegungen für Laravel-JWT-APIs

Beim Wechsel von der lokalen Entwicklung zu einem Produktionsserver beeinflussen mehrere umgebungsspezifische Faktoren das JWT-Verhalten:

  • Zeitzonenkonsistenz: JWT-`iat`-, `nbf`- und `exp`-Claims sind Unix-Zeitstempel. Stellen Sie sicher, dass Ihre Server-Zeitzone auf UTC gesetzt ist (`date.timezone = UTC` in `php.ini`), um eine Token-Ablehnung durch Zeitabweichungen zu verhindern.
  • OPcache: Aktivieren Sie PHP OPcache, um den Overhead beim Laden von JWT-Bibliotheksdateien bei jeder Anfrage zu reduzieren. Dies wirkt sich besonders bei stark frequentierten APIs aus.
  • Queue-Worker für Token-Bereinigung: Wenn Sie benutzerdefinierte Token-Blacklist-Bereinigungsjobs implementieren, stellen Sie sicher, dass Ihr Queue-Worker als überwachter Prozess läuft (Supervisor oder systemd).
  • Umgebungsvariablenverwaltung: Verwenden Sie auf VPS-Control-Panels den Umgebungsvariablenmanager des Panels, anstatt `.env` direkt in der Produktion zu bearbeiten, um versehentliche Überschreibungen bei Deployments zu vermeiden.

Entscheidungs-Checkliste vor dem Go-Live

Verwenden Sie diese Checkliste, um zu überprüfen, ob Ihre Implementierung produktionsreif ist:

  • `JWT_SECRET` hat mindestens 32 Zeichen, ist zufällig generiert und nicht in die Versionskontrolle übertragen
  • `blacklist_enabled` ist in `config/jwt.php` auf `true` gesetzt
  • Token-TTL beträgt 30 Minuten oder weniger für Access-Token
  • Refresh-TTL ist auf einen Wert gesetzt, der Ihrer Sitzungsrichtlinie entspricht
  • Alle API-Endpunkte werden ausschließlich über HTTPS bereitgestellt
  • Rate-Limiting ist auf `/login`- und `/register`-Endpunkte angewendet
  • Der `unauthenticated`-Exception-Handler gibt JSON zurück, keine HTML-Weiterleitung
  • Benutzerdefinierte Claims enthalten keine Passwörter, Secrets oder sensible personenbezogene Daten
  • Der Cache-Treiber ist Redis oder Memcached (nicht `file`) in Multi-Server-Deployments
  • Authentifizierungsereignisse werden protokolliert und überwacht
  • Rollenänderungen, die sofortige Wirkung erfordern, werden über Blacklisting behandelt, nicht allein durch Claim-Ablauf
  • `.env`-Dateiberechtigungen sind auf den Web-Server-Benutzer beschränkt

FAQ

Was ist der Unterschied zwischen `JWT_SECRET` und `APP_KEY` in Laravel?

`APP_KEY` wird von Laravels Verschlüsselungsdienst zum Verschlüsseln von Cookies, Sitzungsdaten und Werten verwendet, die durch `Crypt::encrypt()` übergeben werden. `JWT_SECRET` wird ausschließlich von `tymon/jwt-auth` zum Signieren und Verifizieren von JSON Web Tokens verwendet. Sie sind kryptografisch unabhängig und dienen völlig unterschiedlichen Zwecken. Beide müssen geheim gehalten werden.

Warum gibt mein JWT-Token weiterhin 401 zurück, obwohl es noch nicht abgelaufen ist?

Die häufigsten Ursachen sind: Das Token wurde auf die Blacklist gesetzt (z. B. nach einer Abmeldung oder Aktualisierung), das `JWT_SECRET` wurde nach der Ausstellung des Tokens rotiert, der Cache-Treiber, der die Blacklist speichert, ist nicht verfügbar, oder es gibt eine Zeitabweichung zwischen dem ausstellenden Server und dem validierenden Server, die die `leeway`-Einstellung in `config/jwt.php` überschreitet. Überprüfen Sie diese in der angegebenen Reihenfolge.

Kann ich JWT-Authentifizierung mit Laravel-Queues oder Konsolenbefehlen verwenden?

JWT ist für die HTTP-Anfrage-Authentifizierung konzipiert. Innerhalb von Queue-Jobs oder Artisan-Befehlen gibt es keinen HTTP-Anfrage-Kontext, sodass Sie einen Benutzer nicht über Middleware aus einem Token auflösen können. Übergeben Sie stattdessen den Primärschlüssel des Benutzers als Job-Parameter und laden Sie das Modell direkt mit `User::find($userId)`.

Wie gehe ich mit gleichzeitigen Anfragen während der Token-Aktualisierung um, ohne 401-Fehler zu erhalten?

Setzen Sie `blacklist_grace_period` in `config/jwt.php` auf einen Wert zwischen 10 und 30 Sekunden. Während dieses Zeitfensters wird ein Token, das gerade aktualisiert wurde (und technisch auf der Blacklist steht), weiterhin akzeptiert. Dies verhindert Race Conditions bei Clients, die mehrere gleichzeitige Anfragen stellen, während eine Aktualisierung im Gange ist.

Ist `tymon/jwt-auth` mit Laravel 11 kompatibel?

Zum aktuellen Release-Zyklus unterstützt `tymon/jwt-auth` Version `2.x` Laravel 10 und 11 über den `dev-develop`-Branch oder getaggte Releases, die Kompatibilität deklarieren. Überprüfen Sie immer die `composer.json`-Einschränkungen des Pakets und den GitHub-Issue-Tracker, bevor Sie Laravel-Versionen in einem Projekt aktualisieren, das von diesem Paket abhängt. Erwägen Sie, die Paketversion in `composer.json` zu fixieren, um unerwartete Breaking Changes während `composer update` zu vermeiden.

15%

15% auf alle Hosting-Dienste sparen

Teste deine Fähigkeiten und erhalte Rabatt auf jeden Hosting-Plan

Benutze den Code:

Skills
Anfangen