15%

Zaoszczędź 15% na wszystkich usługach hostingowych

Sprawdź swoje umiejętności i zdobądź Rabat na dowolny plan hostingowy

Użyj kodu:

Skills
Rozpocznij
08.10.2024

Budowanie bezpiecznego API Laravel z uwierzytelnianiem JWT

Uwierzytelnianie JWT (JSON Web Token) w Laravel zapewnia bezstanowy, kryptograficznie podpisany mechanizm weryfikacji konsumentów API bez przechowywania sesji po stronie serwera. JWT koduje ładunek — zazwyczaj tożsamość użytkownika i roszczenia — w kompaktowy, bezpieczny dla URL ciąg znaków podpisany kluczem tajnym lub RSA, umożliwiając każdej usłudze posiadającej klucz weryfikacyjny niezależną walidację tokenu.

Ten przewodnik obejmuje pełną implementację uwierzytelniania JWT w API Laravel przy użyciu pakietu `tymon/jwt-auth`, w tym konfigurację, konfigurację modelu, logikę kontrolera, ochronę tras, strategię odświeżania tokenów i utwardzanie produkcyjne. Każdy krok zawiera kontekst techniczny wykraczający poza powierzchowne samouczki.

Wymagania wstępne i założenia środowiskowe

Przed rozpoczęciem potwierdź następujące kwestie:

  • PHP 8.1 lub wyższy (PHP 8.2 zalecany dla Laravel 11)
  • Laravel 10 lub 11 zainstalowany przez Composer
  • Composer 2.x
  • MySQL 8.0, PostgreSQL 15 lub dowolna baza danych kompatybilna z PDO
  • Skonfigurowany plik `.env` z prawidłowymi poświadczeniami `DB_*`
  • Podstawowa znajomość kontenera usług Laravel, middleware i Eloquent ORM

Jeśli wdrażasz to API w środowisku produkcyjnym, plan Hostingu VPS z pełnym dostępem root daje Ci kontrolę potrzebną do konfiguracji PHP-FPM, bezpiecznego zarządzania zmiennymi środowiskowymi i prawidłowego ustawiania uprawnień do plików — wszystko to jest kluczowe dla zarządzania kluczem tajnym JWT.

Krok 1: Utwórz nowy projekt Laravel

“`bash

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

cd laravel-jwt-api

“`

Zweryfikuj instalację:

“`bash

php artisan –version

“`

Ustaw klucz aplikacji, jeśli nie został wygenerowany automatycznie:

“`bash

php artisan key:generate

“`

`APP_KEY` w `.env` jest oddzielny od klucza tajnego JWT. Oba są wymagane i służą różnym celom kryptograficznym — `APP_KEY` chroni zaszyfrowane pliki cookie i dane sesji, podczas gdy `JWT_SECRET` podpisuje tokeny.

Krok 2: Zainstaluj pakiet uwierzytelniania JWT

Pakiet `tymon/jwt-auth` jest de facto standardem dla JWT w Laravel. Zainstaluj go:

“`bash

composer require tymon/jwt-auth

“`

Opublikuj konfigurację pakietu:

“`bash

php artisan vendor:publish –provider="TymonJWTAuthProvidersLaravelServiceProvider"

“`

Tworzy to `config/jwt.php`, który kontroluje TTL tokenu, TTL odświeżania, algorytm, zachowanie czarnej listy i wymagane roszczenia. Przejrzyj ten plik uważnie — wartości domyślne są rozsądne dla środowiska deweloperskiego, ale wymagają dostrojenia dla produkcji.

Kluczowe parametry konfiguracji w `config/jwt.php`:

ParametrDomyślnyZalecenie produkcyjne
`ttl`60 minut15–30 minut
`refresh_ttl`20160 minut (2 tygodnie)1440–10080 minut
`algo``HS256``RS256` dla systemów rozproszonych
`blacklist_enabled``true`Musi być `true`
`blacklist_grace_period`0 sekund10–30 sekund dla równoczesnych żądań
`required_claims``['iss','iat','exp','nbf','sub','jti']`Zachowaj wszystkie; dodaj `aud` dla API wielodostępnych

Krok 3: Wygeneruj klucz tajny JWT

“`bash

php artisan jwt:secret

“`

Dołącza to `JWT_SECRET` do pliku `.env`. Ta wartość jest używana jako klucz podpisywania HMAC-SHA256 dla wszystkich tokenów przy użyciu domyślnego algorytmu `HS256`.

Krytyczne uwagi dotyczące bezpieczeństwa:

  • Nigdy nie commituj `.env` do kontroli wersji. Natychmiast dodaj go do `.gitignore`.
  • W przypadku współdzielonego potoku wdrożeniowego, wstrzykuj `JWT_SECRET` jako zmienną środowiskową przez system CI/CD zamiast przechowywać go w pliku.
  • Jeśli rotacja klucza tajnego zostanie przeprowadzona, wszystkie istniejące tokeny są natychmiast unieważniane. Odpowiednio zaplanuj okna rotacji i poinformuj o nich konsumentów API.
  • W architekturach mikroserwisów, gdzie wiele usług musi weryfikować tokeny, przełącz się na `RS256`. Wygeneruj parę kluczy RSA, przechowuj klucz prywatny w usłudze uwierzytelniania i dystrybuuj tylko klucz publiczny do usług konsumujących.

Krok 4: Skonfiguruj strażnika uwierzytelniania

Otwórz `config/auth.php` i zaktualizuj sekcje defaults i guards:

“`php

'defaults' => [

'guard' => 'api',

'passwords' => 'users',

],

'guards' => [

'web' => [

'driver' => 'session',

'provider' => 'users',

],

'api' => [

'driver' => 'jwt',

'provider' => 'users',

],

],

“`

Instruuje to system uwierzytelniania Laravel, aby używał sterownika JWT podczas rozwiązywania strażnika `api`. Middleware `auth:api` będzie teraz delegować walidację tokenów do `tymon/jwt-auth` zamiast Laravel Passport lub domyślnego sterownika tokenów.

Nie usuwaj strażnika `web`. Wiele wewnętrznych komponentów Laravel zależy od niego, a jego usunięcie powoduje nieoczekiwane błędy w poleceniach konsoli i pracownikach kolejek, które wchodzą w interakcję z systemem uwierzytelniania.

Krok 5: Utwórz model użytkownika i migrację

Jeśli domyślny model `User` i migracja już istnieją (tak jest w przypadku świeżej instalacji Laravel), możesz je modyfikować bezpośrednio. Jeśli zaczynasz od zera:

“`bash

php artisan make:model User -m

“`

Otwórz plik migracji w `database/migrations/` i zdefiniuj schemat:

“`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();

});

}

“`

Uruchom migrację:

“`bash

php artisan migrate

“`

Uwaga produkcyjna: Zawsze uruchamiaj migracje z flagą `–force` w środowiskach produkcyjnych, gdzie `APP_ENV=production`, ponieważ Laravel w przeciwnym razie wyświetli monit o potwierdzenie:

“`bash

php artisan migrate –force

“`

Krok 6: Zaimplementuj interfejs JWTSubject w modelu użytkownika

Pakiet `tymon/jwt-auth` wymaga, aby Twój model uwierzytelniający implementował kontrakt `JWTSubject`. Otwórz `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 [];

}

}

“`

O niestandardowych roszczeniach: Metoda `getJWTCustomClaims()` to miejsce, gdzie osadzasz dane specyficzne dla aplikacji bezpośrednio w ładunku tokenu. Typowe przypadki użycia obejmują osadzanie `role`, `tenant_id` lub `permissions`, aby usługi downstream mogły podejmować decyzje autoryzacyjne bez wyszukiwania w bazie danych. Bądź przemyślany w kwestii tego, co osadzasz — każde roszczenie zwiększa rozmiar tokenu i jest czytelne dla każdego, kto zdekoduje ładunek base64. Nigdy nie osadzaj wrażliwych danych, takich jak hasła lub dane osobowe.

Krok 7: Zbuduj kontroler uwierzytelniania

“`bash

php artisan make:controller AuthController

“`

Wypełnij `app/Http/Controllers/AuthController.php` pełną logiką uwierzytelniania:

“`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,

]);

}

}

“`

Dlaczego jawne określenie strażnika ma znaczenie: Wywołanie `Auth::attempt()` bez określenia strażnika powraca do domyślnego strażnika. Jeśli zmieniłeś domyślny na `api`, to działa — ale jest kruche. Zawsze wywołuj `Auth::guard('api')->attempt()` jawnie, aby uniknąć subtelnych błędów, gdy domyślny strażnik zmienia się podczas refaktoryzacji.

Krok 8: Zdefiniuj trasy API

Otwórz `routes/api.php` i zdefiniuj trasy uwierzytelniania i chronione:

“`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);

});

“`

Strategia prefiksu tras: Grupowanie punktów końcowych uwierzytelniania pod `/api/auth/` jest powszechnie przyjętą konwencją, która sprawia, że dokumentacja API jest bardziej przejrzysta i upraszcza reguły ograniczania szybkości — możesz stosować bardziej rygorystyczne ograniczanie do `/api/auth/login` niezależnie od punktów końcowych zasobów.

Krok 9: Ochrona tras i obsługa błędów middleware

Middleware `auth:api` Laravel zwróci odpowiedź `401 Unauthenticated`, gdy token jest brakujący, wygasły lub nieprawidłowy. Aby zwrócić spójną odpowiedź JSON zamiast przekierowania HTML, nadpisz metodę `unauthenticated` w `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'));

}

“`

Bez tego nadpisania klienci API otrzymują przekierowanie HTML 302 do strony logowania, która nie istnieje w czystej aplikacji API — częste źródło zamieszania podczas testowania integracji.

Krok 10: Strategia odświeżania tokenów i czarna lista

Bezstanowa natura JWT tworzy napięcie: tokeny są samowystarczalne i ważne do wygaśnięcia, ale potrzebujesz sposobu na ich unieważnienie przy wylogowaniu. Pakiet `tymon/jwt-auth` rozwiązuje to za pomocą czarnej listy tokenów opartej na sterowniku pamięci podręcznej Laravel.

Jak działa czarna lista:

  1. Przy wylogowaniu, roszczenie `jti` (JWT ID) tokenu jest przechowywane w pamięci podręcznej z TTL odpowiadającym pozostałemu czasowi życia tokenu.
  2. Przy każdym uwierzytelnionym żądaniu middleware sprawdza czarną listę przed zaakceptowaniem tokenu.
  3. Ustawienie `blacklist_grace_period` pozwala na krótkie okno, w którym token będący w trakcie odświeżania może być nadal używany, zapobiegając wyścigom w klientach wykonujących równoczesne żądania.

Upewnij się, że Twój sterownik pamięci podręcznej to obsługuje. Domyślny sterownik `file` działa dla wdrożeń na jednym serwerze. W przypadku poziomo skalowanych API działających na wielu węzłach — co jest powszechne przy używaniu Serwerów Dedykowanych w konfiguracji z równoważeniem obciążenia — przełącz się na Redis lub Memcached:

“`env

CACHE_DRIVER=redis

REDIS_HOST=127.0.0.1

REDIS_PORT=6379

“`

Przepływ odświeżania tokenów:

“`

Client API Server

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

“`

Stary token jest natychmiast umieszczany na czarnej liście po odświeżeniu. Klienci muszą przechowywać nowy token i odrzucić stary. Zaimplementuj to jako interceptor Axios lub odpowiednik w swoim frontendzie, aby obsługiwać odświeżanie tokenów w sposób przezroczysty.

Krok 11: Testowanie API

Użyj `curl` lub Postman, aby zweryfikować każdy punkt końcowy.

Zarejestruj użytkownika:

“`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!"

}'

“`

Oczekiwana odpowiedź (`201 Created`):

“`json

{

"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…",

"token_type": "bearer",

"expires_in": 3600

}

“`

Zaloguj się:

“`bash

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

-H "Content-Type: application/json"

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

“`

Uzyskaj dostęp do chronionej trasy:

“`bash

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

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

Odśwież token:

“`bash

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

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

Wyloguj się:

“`bash

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

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

JWT vs. Sesja vs. Laravel Sanctum vs. Passport

Zrozumienie, kiedy JWT jest właściwym wyborem, wymaga porównania go z alternatywami dostępnymi w ekosystemie Laravel.

KryteriumJWT (`tymon/jwt-auth`)Laravel SanctumLaravel PassportOparte na sesji
**Stanowość**BezstanoweBezstanowe (tokeny SPA) / Stanowe (pliki cookie)Stanowe (tokeny DB)Stanowe
**Przechowywanie tokenów**Po stronie klientaPo stronie klienta lub plik cookieBaza danychSesja po stronie serwera
**Unieważnianie**Czarna lista (pamięć podręczna)Natychmiastowe (usunięcie z DB)Natychmiastowe (usunięcie z DB)Natychmiastowe
**Skalowalność**Doskonała (brak DB na żądanie)DobraUmiarkowana (wyszukiwanie DB na żądanie)Słaba (potrzebna synchronizacja sesji)
**Obsługa OAuth2**NieNieTak (pełny serwer OAuth2)Nie
**Złożoność**ŚredniaNiskaWysokaNiska
**Najlepsze dla**Bezstanowe API, mikroserwisySPA, aplikacje mobilneKlienci OAuth innych firmTradycyjne aplikacje webowe
**Introspekcja tokenów**Dekodowanie ładunku po stronie klientaWymaga wywołania APIWymaga wywołania APINie dotyczy

Kiedy wybrać JWT zamiast Sanctum: Jeśli Twoje API jest konsumowane przez klientów zewnętrznych, aplikacje mobilne lub mikroserwisy, które nie mogą współdzielić pliku cookie sesji lub połączenia z bazą danych z Twoją aplikacją Laravel, samowystarczalna natura JWT jest znaczącą zaletą. Jeśli budujesz własne SPA na tej samej domenie, Sanctum z uwierzytelnianiem opartym na plikach cookie jest prostszy i całkowicie eliminuje obawy dotyczące bezpieczeństwa przechowywania tokenów.

Utwardzanie bezpieczeństwa produkcyjnego

Działająca implementacja JWT nie jest domyślnie bezpieczna. Zastosuj te środki utwardzające przed uruchomieniem produkcyjnym:

1. Bezwarunkowo wymuszaj HTTPS

Tokeny JWT przesyłane przez HTTP są trywialnie przechwytywalne. Wymuszaj TLS na poziomie serwera webowego i przekierowuj cały ruch HTTP. Połącz to z Certyfikatem SSL, aby zapewnić szyfrowany transport dla każdego żądania API.

2. Ustaw agresywne TTL tokenów

Krótkotrwałe tokeny dostępu (15–30 minut) w połączeniu z dłużej żyjącymi tokenami odświeżania (7–14 dni) ograniczają zasięg skradzionego tokenu. Zaktualizuj `config/jwt.php`:

“`php

'ttl' => 15,

'refresh_ttl' => 10080,

“`

3. Zastosuj ograniczanie szybkości do punktów końcowych uwierzytelniania

Wbudowany middleware throttle Laravel zapobiega atakom brute-force:

“`php

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

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

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

});

“`

Ogranicza to każdy adres IP do 10 żądań na minutę na punktach końcowych uwierzytelniania.

4. Waliduj roszczenie `aud` dla API wielodostępnych

Jeśli Twoje API obsługuje wiele aplikacji klienckich, osadź i waliduj roszczenie `audience`, aby zapobiec ponownemu użyciu tokenów między usługami:

“`php

// In getJWTCustomClaims()

return [

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

];

“`

5. Chroń JWT_SECRET na poziomie systemu operacyjnego

Ustaw restrykcyjne uprawnienia do pliku `.env`:

“`bash

chmod 640 .env

chown www-data:www-data .env

“`

Na prawidłowo skonfigurowanym VPS z cPanel możesz zarządzać własnością plików i uprawnieniami przez Menedżer plików panelu lub SSH bez ryzyka ujawnienia kluczy tajnych innym użytkownikom systemu.

6. Rejestruj zdarzenia uwierzytelniania

Zintegruj system zdarzeń Laravel, aby rejestrować nieudane próby logowania, odświeżenia tokenów i wylogowania w scentralizowanej usłudze logowania. Jest to niezbędne do wykrywania anomalii.

Dodawanie kontroli dostępu opartej na rolach

Niestandardowe roszczenia ułatwiają osadzanie ról bezpośrednio w tokenie:

“`php

// In User model

public function getJWTCustomClaims(): array

{

return [

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

];

}

“`

Utwórz middleware do egzekwowania wymagań dotyczących ról:

“`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);

}

}

“`

Zarejestruj go w `app/Http/Kernel.php` (Laravel 10) lub `bootstrap/app.php` (Laravel 11) i zastosuj do tras:

“`php

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

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

});

“`

Zastrzeżenie: Dane ról osadzone w tokenie są aktualne tylko do momentu wygaśnięcia tokenu. Jeśli rola użytkownika zmieni się, stary token nadal przyznaje starą rolę do momentu wygaśnięcia lub odświeżenia. W przypadku zmian ról wymagających wysokiego bezpieczeństwa (np. natychmiastowe cofnięcie dostępu administratora) połącz umieszczanie tokenów na czarnej liście z krótkim TTL lub wykonaj sprawdzenie roli w bazie danych w middleware obok sprawdzenia roszczenia.

Uwagi dotyczące wdrożenia dla API Laravel JWT

Podczas przechodzenia z lokalnego środowiska deweloperskiego na serwer produkcyjny, kilka czynników specyficznych dla środowiska wpływa na zachowanie JWT:

  • Spójność strefy czasowej: Roszczenia `iat`, `nbf` i `exp` JWT są znacznikami czasu Unix. Upewnij się, że strefa czasowa serwera jest ustawiona na UTC (`date.timezone = UTC` w `php.ini`), aby zapobiec odrzucaniu tokenów z powodu przesunięcia zegara.
  • OPcache: Włącz PHP OPcache, aby zmniejszyć narzut związany z ładowaniem plików biblioteki JWT przy każdym żądaniu. Ma to szczególne znaczenie w przypadku API o dużym ruchu.
  • Pracownicy kolejek do czyszczenia tokenów: Jeśli implementujesz niestandardowe zadania czyszczenia czarnej listy tokenów, upewnij się, że pracownik kolejki działa jako nadzorowany proces (Supervisor lub systemd).
  • Zarządzanie zmiennymi środowiskowymi: Na Panelach sterowania VPS używaj menedżera zmiennych środowiskowych panelu zamiast bezpośredniego edytowania `.env` w produkcji, aby uniknąć przypadkowego nadpisania podczas wdrożeń.

Lista kontrolna decyzji przed uruchomieniem produkcyjnym

Użyj tej listy kontrolnej, aby sprawdzić, czy Twoja implementacja jest gotowa do produkcji:

  • `JWT_SECRET` ma co najmniej 32 znaki, jest losowo wygenerowany i nie jest zacommitowany do kontroli wersji
  • `blacklist_enabled` jest ustawiony na `true` w `config/jwt.php`
  • TTL tokenu wynosi 30 minut lub mniej dla tokenów dostępu
  • TTL odświeżania jest ustawiony na wartość odpowiednią dla Twojej polityki sesji
  • Wszystkie punkty końcowe API są obsługiwane wyłącznie przez HTTPS
  • Ograniczanie szybkości jest stosowane do punktów końcowych `/login` i `/register`
  • Obsługa wyjątków `unauthenticated` zwraca JSON, a nie przekierowanie HTML
  • Niestandardowe roszczenia nie zawierają haseł, kluczy tajnych ani wrażliwych danych osobowych
  • Sterownik pamięci podręcznej to Redis lub Memcached (nie `file`) w wdrożeniach wieloserwerowych
  • Zdarzenia uwierzytelniania są rejestrowane i monitorowane
  • Zmiany ról wymagające natychmiastowego efektu są obsługiwane przez umieszczanie na czarnej liście, a nie tylko przez wygaśnięcie roszczenia
  • Uprawnienia do pliku `.env` są ograniczone do użytkownika serwera webowego

FAQ

Jaka jest różnica między `JWT_SECRET` a `APP_KEY` w Laravel?

`APP_KEY` jest używany przez usługę szyfrowania Laravel do szyfrowania plików cookie, danych sesji i wartości przekazywanych przez `Crypt::encrypt()`. `JWT_SECRET` jest używany wyłącznie przez `tymon/jwt-auth` do podpisywania i weryfikacji JSON Web Tokenów. Są one kryptograficznie niezależne i służą zupełnie różnym celom. Oba muszą być utrzymywane w tajemnicy.

Dlaczego mój token JWT ciągle zwraca 401, mimo że nie wygasł?

Najczęstsze przyczyny to: token został umieszczony na czarnej liście (np. po wylogowaniu lub odświeżeniu), `JWT_SECRET` został zmieniony po wydaniu tokenu, sterownik pamięci podręcznej przechowujący czarną listę jest niedostępny lub istnieje przesunięcie zegara między serwerem wydającym a serwerem walidującym przekraczające ustawienie `leeway` w `config/jwt.php`. Sprawdź każdą z tych przyczyn po kolei.

Czy mogę używać uwierzytelniania JWT z kolejkami Laravel lub poleceniami konsoli?

JWT jest przeznaczony do uwierzytelniania żądań HTTP. Wewnątrz zadań kolejki lub poleceń Artisan nie ma kontekstu żądania HTTP, więc nie możesz rozwiązać użytkownika z tokenu przez middleware. Zamiast tego przekaż klucz główny użytkownika jako parametr zadania i załaduj model bezpośrednio za pomocą `User::find($userId)`.

Jak obsługiwać równoczesne żądania podczas odświeżania tokenu bez otrzymywania błędów 401?

Ustaw `blacklist_grace_period` w `config/jwt.php` na wartość między 10 a 30 sekund. W tym oknie token, który właśnie został odświeżony (i technicznie umieszczony na czarnej liście), będzie nadal akceptowany. Zapobiega to wyścigom w klientach, które wysyłają wiele równoczesnych żądań podczas trwającego odświeżania.

Czy `tymon/jwt-auth` jest kompatybilny z Laravel 11?

Według aktualnego cyklu wydań, `tymon/jwt-auth` wersja `2.x` obsługuje Laravel 10 i 11 przez gałąź `dev-develop` lub oznaczone wydania deklarujące kompatybilność. Zawsze sprawdzaj ograniczenia `composer.json` pakietu i tracker problemów GitHub przed aktualizacją wersji Laravel w projekcie zależnym od tego pakietu. Rozważ przypięcie wersji pakietu w `composer.json`, aby uniknąć nieoczekiwanych zmian łamiących kompatybilność podczas `composer update`.

15%

Zaoszczędź 15% na wszystkich usługach hostingowych

Sprawdź swoje umiejętności i zdobądź Rabat na dowolny plan hostingowy

Użyj kodu:

Skills
Rozpocznij