Membuat token itu mudah; kebersihan jangka panjang justru ditentukan oleh pencabutan. Ponsel hilang, laptop dijual, atau integrasi pihak ketiga selesai dipakai — semuanya menuntut aksesnya dimatikan seketika. Karena verifikasi token selalu berakhir di baris personal_access_tokens, mencabut akses di Sanctum bermakna menghapus baris tersebut; tidak ada daftar hitam terpisah yang perlu dirawat. Chapter ini membahas empat granularitas pencabutan — satu token, perangkat saat ini, semua perangkat, dan kedaluwarsa otomatis — semuanya dibuktikan lewat test sungguhan yang mengakhiri request dengan 401.
Mencabut Satu Token #
Cara paling langsung: panggil delete() pada model token yang didapat dari relasi. Token lain milik user yang sama tetap hidup:
<?php
$newToken = $user->createToken('mobile-budi');
// ... suatu saat nanti:
$newToken->accessToken->delete();Kunci ujinya sederhana — request yang sah sebelum pencabutan harus menjadi 401 setelah pencabutan:
<?php
// tests/Feature/Sanctum/RevokingTest.php (cuplikan)
public function test_token_yang_dihapus_langsung_ditolak(): void
{
$user = User::factory()->create(['email' => '[email protected]']);
$newToken = $user->createToken('mobile-budi');
$plain = $newToken->plainTextToken;
// request pertama: masih sah
$this->withToken($plain)->getJson('/api/profil')->assertStatus(200);
// cabut token
$newToken->accessToken->delete();
// request kedua: ditolak (guard di-reset untuk menyimulasikan
// request yang datang dari proses PHP terpisah seperti di produksi)
$this->app->make('auth')->forgetGuards();
$this->withToken($plain)->getJson('/api/profil')->assertStatus(401);
}Di chapter API Token Management
, tombol hapus di halaman kelola token memanggil endpoint DELETE /api/tokens/{id} yang pada intinya melakukan hal yang sama lewat query builder.
Logout Semua Perangkat vs Perangkat Ini #
Relasi tokens memungkinkan pencabutan massal dalam satu query. Ini tombol “keluar dari semua perangkat” — misalnya saat Budi mencurigai akunnya dibobol:
<?php
$user->tokens()->delete();Adapun untuk tombol “logout” di aplikasi mobile atau SPA berbasis token, kita hanya mencabut token yang sedang dipakai request tersebut. Objek token aktif bisa diambil lewat currentAccessToken():
<?php
// routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('/logout-current', function (Request $request) {
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Token perangkat ini dicabut.']);
})->middleware('auth:sanctum');Pola auth:sanctum + currentAccessToken()->delete() adalah padanan API dari Auth::logout() berbasis session yang kita kenal di chapter Login dan Logout
. Kedua granularitas ini kita kunci dalam satu test:
Output yang Dihasilkan:
PASS Tests\Feature\Sanctum\RevokingTest
✓ token yang dihapus langsung ditolak
✓ logout semua perangkat
✓ logout perangkat ini saja
Tests: 6 passed (10 assertions)Test logout perangkat ini saja memeriksa kombinasi pentingnya: setelah token mobile-budi dicabut lewat endpoint, request berikutnya dari token tersebut ditolak 401, sementara token tablet-budi milik Budi yang sama masih diterima 200.
Kedaluwarsa Otomatis #
Pencabutan manual membutuhkan manusia yang ingat. Dua mekanisme otomatis melengkapinya. Pertama, per token: argumen ketiga createToken() menerima objek DateTimeInterface untuk kolom expires_at:
<?php
use Illuminate\Support\Carbon;
// token hanya berlaku 7 hari
$user->createToken('sementara', ['*'], Carbon::now()->addDays(7));Kedua, global: mengisi expiration di config/sanctum.php (atau env SANCTUM_EXPIRATION) memberlakukan umur maksimum dalam menit untuk semua token — nilai ini mengesampingkan expires_at per token. Kita uji keduanya:
<?php
public function test_token_dengan_expires_at_masa_lalu_ditolak(): void
{
$user = User::factory()->create(['email' => '[email protected]']);
$plain = $user->createToken('lama-budi', ['*'], now()->subMinute())
->plainTextToken;
$this->withToken($plain)->getJson('/api/profil')->assertStatus(401);
}
public function test_expiration_global_mencabut_token_lama(): void
{
config(['sanctum.expiration' => 1]);
$user = User::factory()->create(['email' => '[email protected]']);
$plain = $user->createToken('lama-budi')->plainTextToken;
// token dibuat 5 menit lalu — lebih tua dari batas 1 menit
$user->tokens()->update(['created_at' => now()->subMinutes(5)]);
$this->withToken($plain)->getJson('/api/profil')->assertStatus(401);
}Output yang Dihasilkan:
✓ token dengan expires at masa lalu ditolak
✓ token masa depan masih sah
✓ expiration global mencabut token lamaMerapikan Token Kedaluwarsa #
Penolakan token kedaluwarsa hanya membuat barisnya tidak berlaku; barisnya masih menumpuk di tabel. Sanctum menyediakan perintah sanctum:prune-expired untuk membersihkannya, dengan opsi --hours menentukan tenggang setelah kedaluwarsa:
php artisan sanctum:prune-expired --hours=24Output yang Dihasilkan:
Pruning tokens with expired expires_at timestamps ............. 12.65ms DONE
WARN Expiration value not specified in configuration file.
INFO Tokens expired for more than [24 hours] pruned successfully.Baris pertama menghapus baris dengan expires_at yang lampau; peringatan muncul karena sandbox belum mengatur SANCTUM_EXPIRATION. Bila konfigurasi global terisi, perintah ini menjalankan pembersihan tambahan untuk token berumur melebihi expiration. Efek bersihnya terukur di runner sandbox: dua token di database (satu expires_at 30 hari lampau, satu tanpa kedaluwarsa) menjadi satu baris tersisa setelah perintah berjalan — hanya baru-budi yang selamat. Agar tabel tetap ramping, jadwalkan perintah ini di routes/console.php:
<?php
use Illuminate\Support\Facades\Schedule;
Schedule::command('sanctum:prune-expired')->daily();Penjadwalan ini berjalan lewat mekanisme scheduler yang sudah kita bahasi di section Task Scheduling
, jadi tidak ada kode baru yang perlu dipelajari di sini. Keempat granularitas pencabutan kini lengkap, dan satu keterampilan terakhir menutup section ini: menguji semuanya secara efisien lewat actingAs dan Sanctum::actingAs di chapter Pengujian Sanctum
. Dokumentasi resminya ada di dokumentasi Sanctum — token expiration
.