15%

Hemat 15% di Semua Layanan Hosting

Uji kemampuanmu dan dapatkan Diskon pada paket hosting apa saja

Gunakan kode:

Skills
Memulai
08.10.2024

Membangun API Laravel yang Aman dengan Autentikasi JWT

Autentikasi JWT (JSON Web Token) di Laravel menyediakan mekanisme yang ditandatangani secara kriptografis dan stateless untuk memverifikasi konsumen API tanpa penyimpanan sesi di sisi server. JWT mengenkode payload — biasanya identitas pengguna dan klaim — ke dalam string yang ringkas dan aman untuk URL yang ditandatangani dengan kunci rahasia atau RSA, memungkinkan layanan mana pun yang memegang kunci verifikasi untuk memvalidasi token secara independen.

Panduan ini mencakup implementasi lengkap autentikasi JWT dalam API Laravel menggunakan paket `tymon/jwt-auth`, termasuk pengaturan, konfigurasi model, logika controller, perlindungan rute, strategi refresh token, dan penguatan untuk produksi. Setiap langkah mencakup konteks teknis yang melampaui tutorial tingkat permukaan.

Prasyarat dan Asumsi Lingkungan

Sebelum memulai, konfirmasikan hal-hal berikut:

  • PHP 8.1 atau lebih tinggi (PHP 8.2 direkomendasikan untuk Laravel 11)
  • Laravel 10 atau 11 yang diinstal melalui Composer
  • Composer 2.x
  • MySQL 8.0, PostgreSQL 15, atau database yang kompatibel dengan PDO
  • File `.env` yang dikonfigurasi dengan kredensial `DB_*` yang valid
  • Pemahaman dasar tentang service container, middleware, dan Eloquent ORM Laravel

Jika Anda mendeploy API ini ke lingkungan produksi, paket VPS Hosting dengan akses root penuh memberi Anda kendali yang diperlukan untuk mengonfigurasi PHP-FPM, mengelola variabel lingkungan dengan aman, dan mengatur izin file dengan benar — semuanya penting untuk manajemen rahasia JWT.

Langkah 1: Buat Proyek Laravel Baru

“`bash

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

cd laravel-jwt-api

“`

Verifikasi instalasi:

“`bash

php artisan –version

“`

Atur kunci aplikasi Anda jika tidak dibuat secara otomatis:

“`bash

php artisan key:generate

“`

`APP_KEY` di `.env` terpisah dari rahasia JWT. Keduanya diperlukan dan melayani tujuan kriptografis yang berbeda — `APP_KEY` melindungi cookie terenkripsi dan data sesi, sementara `JWT_SECRET` menandatangani token.

Langkah 2: Instal Paket Autentikasi JWT

Paket `tymon/jwt-auth` adalah standar de facto untuk JWT di Laravel. Instal dengan:

“`bash

composer require tymon/jwt-auth

“`

Publikasikan konfigurasi paket:

“`bash

php artisan vendor:publish –provider="TymonJWTAuthProvidersLaravelServiceProvider"

“`

Ini membuat `config/jwt.php`, yang mengontrol TTL token, TTL refresh, algoritma, perilaku blacklist, dan klaim yang diperlukan. Tinjau file ini dengan cermat — defaultnya masuk akal untuk pengembangan tetapi memerlukan penyesuaian untuk produksi.

Parameter konfigurasi utama di `config/jwt.php`:

ParameterDefaultRekomendasi Produksi
`ttl`60 menit15–30 menit
`refresh_ttl`20160 menit (2 minggu)1440–10080 menit
`algo``HS256``RS256` untuk sistem terdistribusi
`blacklist_enabled``true`Harus `true`
`blacklist_grace_period`0 detik10–30 detik untuk permintaan bersamaan
`required_claims``['iss','iat','exp','nbf','sub','jti']`Pertahankan semua; tambahkan `aud` untuk API multi-tenant

Langkah 3: Buat Kunci Rahasia JWT

“`bash

php artisan jwt:secret

“`

Ini menambahkan `JWT_SECRET` ke file `.env` Anda. Nilai ini digunakan sebagai kunci penandatanganan HMAC-SHA256 untuk semua token saat menggunakan algoritma `HS256` default.

Catatan keamanan penting:

  • Jangan pernah melakukan commit `.env` ke version control. Tambahkan ke `.gitignore` segera.
  • Pada pipeline deployment bersama, masukkan `JWT_SECRET` sebagai variabel lingkungan melalui sistem CI/CD Anda daripada menyimpannya dalam file.
  • Jika Anda merotasi rahasia, semua token yang ada langsung tidak valid. Rencanakan jendela rotasi dengan tepat dan komunikasikan kepada konsumen API.
  • Untuk arsitektur layanan mikro di mana beberapa layanan harus memverifikasi token, beralih ke `RS256`. Buat pasangan kunci RSA, simpan kunci privat di layanan autentikasi, dan distribusikan hanya kunci publik ke layanan yang mengonsumsinya.

Langkah 4: Konfigurasi Guard Autentikasi

Buka `config/auth.php` dan perbarui bagian defaults dan guards:

“`php

'defaults' => [

'guard' => 'api',

'passwords' => 'users',

],

'guards' => [

'web' => [

'driver' => 'session',

'provider' => 'users',

],

'api' => [

'driver' => 'jwt',

'provider' => 'users',

],

],

“`

Ini menginstruksikan sistem autentikasi Laravel untuk menggunakan driver JWT saat menyelesaikan guard `api`. Middleware `auth:api` sekarang akan mendelegasikan validasi token ke `tymon/jwt-auth` alih-alih Laravel Passport atau driver token default.

Jangan hapus guard `web`. Banyak komponen internal Laravel bergantung padanya, dan menghapusnya menyebabkan kegagalan tak terduga dalam perintah konsol dan queue worker yang berinteraksi dengan sistem autentikasi.

Langkah 5: Buat Model User dan Migrasi

Jika model `User` dan migrasi default sudah ada (ada dalam instalasi Laravel baru), Anda dapat memodifikasinya langsung. Jika memulai dari awal:

“`bash

php artisan make:model User -m

“`

Buka file migrasi di `database/migrations/` dan definisikan skema:

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

});

}

“`

Jalankan migrasi:

“`bash

php artisan migrate

“`

Catatan produksi: Selalu jalankan migrasi dengan flag `–force` di lingkungan produksi di mana `APP_ENV=production`, karena Laravel akan meminta konfirmasi jika tidak:

“`bash

php artisan migrate –force

“`

Langkah 6: Implementasikan Interface JWTSubject di Model User

Paket `tymon/jwt-auth` mengharuskan model yang dapat diautentikasi Anda mengimplementasikan kontrak `JWTSubject`. Buka `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 [];

}

}

“`

Tentang klaim kustom: Metode `getJWTCustomClaims()` adalah tempat Anda menyematkan data spesifik aplikasi langsung ke dalam payload token. Kasus penggunaan umum meliputi penyematan `role`, `tenant_id`, atau `permissions` sehingga layanan hilir dapat membuat keputusan otorisasi tanpa pencarian database. Berhati-hatilah tentang apa yang Anda sematkan — setiap klaim meningkatkan ukuran token dan dapat dibaca oleh siapa saja yang mendekode base64 payload. Jangan pernah menyematkan data sensitif seperti kata sandi atau PII.

Langkah 7: Bangun Controller Autentikasi

“`bash

php artisan make:controller AuthController

“`

Isi `app/Http/Controllers/AuthController.php` dengan logika autentikasi lengkap:

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

]);

}

}

“`

Mengapa spesifikasi guard eksplisit penting: Memanggil `Auth::attempt()` tanpa menentukan guard akan kembali ke guard default. Jika Anda telah mengubah default ke `api`, ini berfungsi — tetapi tidak stabil. Selalu panggil `Auth::guard('api')->attempt()` secara eksplisit untuk menghindari bug halus saat guard default berubah selama refactoring.

Langkah 8: Definisikan Rute API

Buka `routes/api.php` dan definisikan rute autentikasi dan yang dilindungi:

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

});

“`

Strategi prefix rute: Mengelompokkan endpoint autentikasi di bawah `/api/auth/` adalah konvensi yang banyak diadopsi yang membuat dokumentasi API lebih bersih dan menyederhanakan aturan pembatasan laju — Anda dapat menerapkan throttling yang lebih ketat ke `/api/auth/login` secara independen dari endpoint resource.

Langkah 9: Melindungi Rute dan Menangani Kegagalan Middleware

Middleware `auth:api` Laravel akan mengembalikan respons `401 Unauthenticated` ketika token hilang, kedaluwarsa, atau tidak valid. Untuk mengembalikan respons JSON yang konsisten alih-alih pengalihan HTML, timpa metode `unauthenticated` di `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'));

}

“`

Tanpa penimpaan ini, klien API menerima pengalihan HTML 302 ke halaman login yang tidak ada dalam aplikasi API murni — sumber kebingungan umum selama pengujian integrasi.

Langkah 10: Strategi Refresh Token dan Blacklisting

Sifat stateless JWT menciptakan ketegangan: token bersifat mandiri dan valid hingga kedaluwarsa, tetapi Anda memerlukan cara untuk mencabutnya saat logout. Paket `tymon/jwt-auth` menyelesaikan ini dengan blacklist token yang didukung oleh driver cache Laravel.

Cara kerja blacklist:

  1. Saat logout, klaim `jti` (JWT ID) token disimpan dalam cache dengan TTL yang sesuai dengan sisa masa berlaku token.
  2. Pada setiap permintaan yang diautentikasi, middleware memeriksa blacklist sebelum menerima token.
  3. Pengaturan `blacklist_grace_period` memungkinkan jendela singkat di mana token yang sedang di-refresh masih dapat digunakan, mencegah kondisi balapan pada klien yang membuat permintaan bersamaan.

Pastikan driver cache Anda mendukung ini. Driver `file` default berfungsi untuk deployment server tunggal. Untuk API yang diskalakan secara horizontal yang berjalan di beberapa node — umum saat menggunakan Dedicated Server dalam konfigurasi load-balanced — beralih ke Redis atau Memcached:

“`env

CACHE_DRIVER=redis

REDIS_HOST=127.0.0.1

REDIS_PORT=6379

“`

Alur refresh token:

“`

Client API Server

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

“`

Token lama langsung di-blacklist setelah refresh. Klien harus menyimpan token baru dan membuang yang lama. Implementasikan ini sebagai interceptor Axios atau yang setara di frontend Anda untuk menangani refresh token secara transparan.

Langkah 11: Menguji API

Gunakan `curl` atau Postman untuk memverifikasi setiap endpoint.

Daftarkan pengguna:

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

}'

“`

Respons yang diharapkan (`201 Created`):

“`json

{

"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…",

"token_type": "bearer",

"expires_in": 3600

}

“`

Masuk:

“`bash

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

-H "Content-Type: application/json"

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

“`

Akses rute yang dilindungi:

“`bash

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

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

Refresh token:

“`bash

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

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

Keluar:

“`bash

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

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…"

“`

JWT vs. Sesi vs. Laravel Sanctum vs. Passport

Memahami kapan JWT adalah pilihan yang tepat memerlukan perbandingan dengan alternatif yang tersedia dalam ekosistem Laravel.

KriteriaJWT (`tymon/jwt-auth`)Laravel SanctumLaravel PassportBerbasis Sesi
**Statefulness**StatelessStateless (token SPA) / Stateful (cookie)Stateful (token DB)Stateful
**Penyimpanan token**Sisi klienSisi klien atau cookieDatabaseSesi sisi server
**Pencabutan**Blacklist (cache)Langsung (hapus DB)Langsung (hapus DB)Langsung
**Skalabilitas**Sangat baik (tidak ada DB per permintaan)BaikSedang (pencarian DB per permintaan)Buruk (sinkronisasi sesi diperlukan)
**Dukungan OAuth2**TidakTidakYa (server OAuth2 penuh)Tidak
**Kompleksitas**SedangRendahTinggiRendah
**Terbaik untuk**API stateless, layanan mikroSPA, aplikasi mobileKlien OAuth pihak ketigaAplikasi web tradisional
**Introspeksi token**Dekode payload sisi klienMemerlukan panggilan APIMemerlukan panggilan APIN/A

Kapan memilih JWT daripada Sanctum: Jika API Anda dikonsumsi oleh klien pihak ketiga, aplikasi mobile, atau layanan mikro yang tidak dapat berbagi cookie sesi atau koneksi database dengan aplikasi Laravel Anda, sifat mandiri JWT adalah keunggulan yang signifikan. Jika Anda membangun SPA first-party di domain yang sama, Sanctum dengan autentikasi berbasis cookie lebih sederhana dan sepenuhnya menghindari masalah keamanan penyimpanan token.

Penguatan Keamanan Produksi

Implementasi JWT yang berfungsi tidak secara default aman. Terapkan langkah-langkah penguatan ini sebelum go live:

1. Terapkan HTTPS tanpa syarat

Token JWT yang ditransmisikan melalui HTTP dapat dengan mudah disadap. Terapkan TLS di tingkat web server dan alihkan semua lalu lintas HTTP. Padukan ini dengan Sertifikat SSL untuk memastikan transport terenkripsi untuk setiap permintaan API.

2. Tetapkan TTL token yang agresif

Token akses berumur pendek (15–30 menit) dikombinasikan dengan token refresh berumur lebih panjang (7–14 hari) membatasi dampak token yang dicuri. Perbarui `config/jwt.php`:

“`php

'ttl' => 15,

'refresh_ttl' => 10080,

“`

3. Terapkan pembatasan laju pada endpoint autentikasi

Middleware throttle bawaan Laravel mencegah serangan brute-force:

“`php

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

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

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

});

“`

Ini membatasi setiap IP hingga 10 permintaan per menit pada endpoint autentikasi.

4. Validasi klaim `aud` untuk API multi-tenant

Jika API Anda melayani beberapa aplikasi klien, sematkan dan validasi klaim `audience` untuk mencegah penggunaan ulang token lintas layanan:

“`php

// In getJWTCustomClaims()

return [

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

];

“`

5. Lindungi JWT_SECRET di tingkat OS

Tetapkan izin file yang ketat pada `.env`:

“`bash

chmod 640 .env

chown www-data:www-data .env

“`

Pada VPS dengan cPanel yang dikonfigurasi dengan benar, Anda dapat mengelola kepemilikan dan izin file melalui File Manager atau SSH tanpa risiko mengekspos rahasia kepada pengguna lain di sistem.

6. Catat peristiwa autentikasi

Integrasikan sistem event Laravel untuk mencatat percobaan login yang gagal, refresh token, dan logout ke layanan logging terpusat. Ini penting untuk deteksi anomali.

Menambahkan Kontrol Akses Berbasis Peran

Klaim kustom memudahkan penyematan peran langsung dalam token:

“`php

// In User model

public function getJWTCustomClaims(): array

{

return [

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

];

}

“`

Buat middleware untuk menegakkan persyaratan peran:

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

}

}

“`

Daftarkan di `app/Http/Kernel.php` (Laravel 10) atau `bootstrap/app.php` (Laravel 11) dan terapkan ke rute:

“`php

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

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

});

“`

Peringatan: Data peran yang disematkan dalam token hanya seakurat token itu sendiri. Jika peran pengguna berubah, token lama terus memberikan peran lama hingga kedaluwarsa atau di-refresh. Untuk perubahan peran dengan keamanan tinggi (misalnya, mencabut akses admin segera), kombinasikan blacklisting token dengan TTL pendek atau lakukan pemeriksaan peran database di middleware bersamaan dengan pemeriksaan klaim.

Pertimbangan Deployment untuk API JWT Laravel

Saat berpindah dari pengembangan lokal ke server produksi, beberapa faktor spesifik lingkungan memengaruhi perilaku JWT:

  • Konsistensi zona waktu: Klaim `iat`, `nbf`, dan `exp` JWT adalah timestamp Unix. Pastikan zona waktu server Anda diatur ke UTC (`date.timezone = UTC` di `php.ini`) untuk mencegah penolakan token akibat perbedaan jam.
  • OPcache: Aktifkan PHP OPcache untuk mengurangi overhead pemuatan file library JWT pada setiap permintaan. Ini sangat berdampak pada API dengan lalu lintas tinggi.
  • Queue worker untuk pembersihan token: Jika Anda mengimplementasikan job pembersihan blacklist token kustom, pastikan queue worker Anda berjalan sebagai proses yang diawasi (Supervisor atau systemd).
  • Manajemen variabel lingkungan: Pada Panel Kontrol VPS, gunakan manajer variabel lingkungan panel daripada mengedit `.env` langsung di produksi, untuk menghindari penimpaan yang tidak disengaja selama deployment.

Daftar Periksa Keputusan Sebelum Go Live

Gunakan daftar periksa ini untuk memverifikasi implementasi Anda siap untuk produksi:

  • `JWT_SECRET` minimal 32 karakter, dibuat secara acak, dan tidak di-commit ke version control
  • `blacklist_enabled` diatur ke `true` di `config/jwt.php`
  • TTL token adalah 30 menit atau kurang untuk token akses
  • TTL refresh diatur ke nilai yang sesuai dengan kebijakan sesi Anda
  • Semua endpoint API disajikan secara eksklusif melalui HTTPS
  • Pembatasan laju diterapkan pada endpoint `/login` dan `/register`
  • Handler pengecualian `unauthenticated` mengembalikan JSON, bukan pengalihan HTML
  • Klaim kustom tidak mengandung kata sandi, rahasia, atau PII sensitif
  • Driver cache adalah Redis atau Memcached (bukan `file`) dalam deployment multi-server
  • Peristiwa autentikasi dicatat dan dipantau
  • Perubahan peran yang memerlukan efek segera ditangani melalui blacklisting, bukan hanya kedaluwarsa klaim
  • Izin file `.env` dibatasi untuk pengguna web server

FAQ

Apa perbedaan antara `JWT_SECRET` dan `APP_KEY` di Laravel?

`APP_KEY` digunakan oleh layanan enkripsi Laravel untuk mengenkripsi cookie, data sesi, dan nilai yang diteruskan melalui `Crypt::encrypt()`. `JWT_SECRET` digunakan secara eksklusif oleh `tymon/jwt-auth` untuk menandatangani dan memverifikasi JSON Web Token. Keduanya secara kriptografis independen dan melayani tujuan yang sepenuhnya berbeda. Keduanya harus dijaga kerahasiaannya.

Mengapa token JWT saya terus mengembalikan 401 meskipun belum kedaluwarsa?

Penyebab paling umum adalah: token telah di-blacklist (misalnya, setelah logout atau refresh), `JWT_SECRET` dirotasi setelah token diterbitkan, driver cache yang menyimpan blacklist tidak tersedia, atau ada perbedaan jam antara server penerbit dan server validasi yang melebihi pengaturan `leeway` di `config/jwt.php`. Periksa masing-masing secara berurutan.

Bisakah saya menggunakan autentikasi JWT dengan queue atau perintah konsol Laravel?

JWT dirancang untuk autentikasi permintaan HTTP. Di dalam job queue atau perintah Artisan, tidak ada konteks permintaan HTTP, sehingga Anda tidak dapat menyelesaikan pengguna dari token melalui middleware. Sebagai gantinya, teruskan kunci primer pengguna sebagai parameter job dan muat model secara langsung dengan `User::find($userId)`.

Bagaimana cara menangani permintaan bersamaan selama refresh token tanpa mendapatkan error 401?

Atur `blacklist_grace_period` di `config/jwt.php` ke nilai antara 10 dan 30 detik. Selama jendela ini, token yang baru saja di-refresh (dan secara teknis di-blacklist) masih akan diterima. Ini mencegah kondisi balapan pada klien yang mengirim beberapa permintaan simultan saat refresh sedang berlangsung.

Apakah `tymon/jwt-auth` kompatibel dengan Laravel 11?

Pada siklus rilis saat ini, `tymon/jwt-auth` versi `2.x` mendukung Laravel 10 dan 11 melalui cabang `dev-develop` atau rilis bertag yang menyatakan kompatibilitas. Selalu periksa batasan `composer.json` paket dan pelacak masalah GitHub sebelum meningkatkan versi Laravel dalam proyek yang bergantung pada paket ini. Pertimbangkan untuk menyematkan versi paket di `composer.json` untuk menghindari perubahan yang merusak secara tak terduga selama `composer update`.

15%

Hemat 15% di Semua Layanan Hosting

Uji kemampuanmu dan dapatkan Diskon pada paket hosting apa saja

Gunakan kode:

Skills
Memulai