Laravel Sanctum adalah sebuah paket ringan yang menyediakan sistem autentikasi sederhana untuk API Laravel. Sistem ini sangat ideal untuk Single-Page Applications (SPAs), aplikasi mobile, dan API sederhana yang tidak memerlukan kompleksitas OAuth 2.0. Dalam tutorial ini, kita akan belajar cara membuat sistem keamanan API yang solid menggunakan Laravel Sanctum. Siap? Yuk, mulai!
1. Pengantar: Apa Itu Laravel Sanctum dan Mengapa Kita Menggunakannya?
Pernahkah kamu membuat API dan bingung bagaimana cara mengamankannya? Dulu, pilihan yang populer adalah Passport (implementasi OAuth 2.0 yang lebih rumit), namun untuk proyek kecil dan menengah, seringkali terlalu berlebihan. Di sinilah Laravel Sanctum hadir sebagai penyelamat.
Laravel Sanctum, atau dulunya dikenal sebagai Laravel Airlock, menawarkan solusi autentikasi ringan yang menggunakan token API. Bayangkan, daripada menyimpan kredensial pengguna (username/password) di setiap request, kita menggunakan token yang unik dan sementara. Token ini memberikan akses ke API hanya jika pengguna telah diautentikasi sebelumnya.
Mengapa memilih Laravel Sanctum?
- Sederhana: Konfigurasi dan implementasi jauh lebih mudah dibandingkan OAuth 2.0.
- Ringan: Tidak membebani aplikasi dengan kompleksitas yang tidak perlu.
- Aman: Menggunakan token yang aman untuk melindungi API.
- Cocok untuk SPA dan Mobile App: Ideal untuk aplikasi yang hanya membutuhkan autentikasi token.
- CSRF Protection: Menyediakan perlindungan CSRF untuk aplikasi berbasis browser.
- Stateful dan Stateless Authentication: Mendukung autentikasi berbasis session (stateful) dan token (stateless).
Singkatnya, Laravel Sanctum adalah pilihan yang tepat jika kamu membutuhkan sistem keamanan API yang cepat, mudah, dan aman di Laravel.
2. Persiapan Awal: Instalasi Laravel dan Laravel Sanctum
Sebelum kita mulai membuat sistem keamanan API, pastikan kamu sudah memiliki proyek Laravel yang berjalan. Jika belum, ikuti langkah-langkah berikut:
-
Instal Laravel:
Buka terminal kamu dan jalankan perintah berikut:
composer create-project --prefer-dist laravel/laravel sanctum-api cd sanctum-apiGanti
sanctum-apidengan nama proyek yang kamu inginkan. -
Konfigurasi Database:
Edit file
.envdan sesuaikan konfigurasi database dengan kredensial database kamu:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nama_database_kamu DB_USERNAME=username_database_kamu DB_PASSWORD=password_database_kamuPastikan database dengan nama yang kamu tentukan sudah dibuat.
-
Install Laravel Sanctum:
Kembali ke terminal dan jalankan perintah berikut:
composer require laravel/sanctum -
Publish Konfigurasi dan Migrasi Sanctum:
Perintah ini akan membuat file konfigurasi
config/sanctum.phpdan file migrasi database.php artisan vendor:publish --provider="LaravelSanctumSanctumServiceProvider" -
Migrasi Database:
Jalankan migrasi untuk membuat tabel yang dibutuhkan oleh Sanctum.
php artisan migrate -
Setup Model User:
Pastikan model
Userkamu menggunakan traitLaravelSanctumHasApiTokens. Bukaapp/Models/User.phpdan tambahkan:<?php namespace AppModels; use IlluminateContractsAuthMustVerifyEmail; use IlluminateDatabaseEloquentFactoriesHasFactory; use IlluminateFoundationAuthUser as Authenticatable; use IlluminateNotificationsNotifiable; use LaravelSanctumHasApiTokens; // Tambahkan ini class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; // ... kode lainnya ... }
Dengan langkah-langkah ini, kamu sudah berhasil menginstal Laravel dan Laravel Sanctum. Sekarang, kita siap untuk membangun API!
3. Membuat Controller dan Routes API Authentication (Registrasi, Login, Logout)
Sekarang, kita akan membuat controller dan routes untuk menangani proses registrasi (pendaftaran), login (masuk), dan logout (keluar) pengguna.
-
Buat Controller
AuthController:Jalankan perintah berikut untuk membuat controller:
php artisan make:controller AuthController -
Edit
AuthController:Buka
app/Http/Controllers/AuthController.phpdan tambahkan kode berikut:<?php namespace AppHttpControllers; use AppModelsUser; use IlluminateHttpRequest; use IlluminateSupportFacadesHash; use IlluminateSupportFacadesValidator; use IlluminateSupportStr; class AuthController extends Controller { public function register(Request $request) { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8', ]); if ($validator->fails()) { return response()->json(['errors' => $validator->errors()], 422); } $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); $token = $user->createToken('auth_token')->plainTextToken; return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', ]); } public function login(Request $request) { $validator = Validator::make($request->all(), [ 'email' => 'required|string|email|max:255', 'password' => 'required|string', ]); if ($validator->fails()) { return response()->json(['errors' => $validator->errors()], 422); } $user = User::where('email', $request->email)->first(); if (!$user || !Hash::check($request->password, $user->password)) { return response()->json([ 'message' => 'Invalid credentials' ], 401); } $token = $user->createToken('auth_token')->plainTextToken; return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', ]); } public function logout(Request $request) { $request->user()->currentAccessToken()->delete(); return response()->json([ 'message' => 'Successfully logged out' ]); } public function me(Request $request) { return response()->json($request->user()); } }Penjelasan Kode:
register(): Menerima dataname,email, danpassword, melakukan validasi, membuat user baru, dan menghasilkan token API.login(): Menerima dataemaildanpassword, melakukan validasi, mencari user berdasarkan email, memverifikasi password, dan menghasilkan token API.logout(): Menghapus token API yang sedang aktif untuk user yang melakukan request.me(): Mengembalikan informasi user yang terautentikasi.
-
Definisikan Routes API:
Buka
routes/api.phpdan tambahkan kode berikut:<?php use AppHttpControllersAuthController; use IlluminateHttpRequest; use IlluminateSupportFacadesRoute; Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']); Route::middleware('auth:sanctum')->group(function () { Route::post('/logout', [AuthController::class, 'logout']); Route::get('/me', [AuthController::class, 'me']); });Penjelasan Kode:
/registerdan/logindiakses tanpa autentikasi (publik)./logoutdan/medilindungi oleh middlewareauth:sanctum, yang berarti hanya pengguna yang terautentikasi (memiliki token API yang valid) yang bisa mengaksesnya.
4. Mengamankan Routes dengan Middleware auth:sanctum
Seperti yang kita lihat di bagian sebelumnya, middleware auth:sanctum memegang peranan penting dalam mengamankan routes API kita. Middleware ini memverifikasi apakah request yang masuk memiliki token API yang valid. Jika tidak, request akan ditolak.
Bagaimana cara kerjanya?
- Pencarian Token:
auth:sanctummencari token API di headerAuthorization(dengan formatBearer <token>). - Validasi Token: Sanctum akan memverifikasi apakah token tersebut valid dan terkait dengan seorang user.
- Otentikasi User: Jika token valid, user akan diotentikasi dan tersedia di dalam request (
$request->user()). - Akses Diberikan: Jika user berhasil diotentikasi, request akan diizinkan untuk melewati middleware dan mengakses route yang dituju.
- Akses Ditolak: Jika token tidak valid atau tidak ditemukan, request akan ditolak dengan kode status HTTP 401 (Unauthorized).
Contoh Penggunaan:
Kita sudah melihat contoh penggunaan auth:sanctum di routes/api.php. Kita bisa menggunakannya untuk melindungi route secara individual:
Route::get('/profile', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Atau, kita bisa menggunakannya untuk melindungi sekelompok route:
Route::middleware('auth:sanctum')->group(function () {
Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts', [PostController::class, 'store']);
Route::get('/posts/{id}', [PostController::class, 'show']);
Route::put('/posts/{id}', [PostController::class, 'update']);
Route::delete('/posts/{id}', [PostController::class, 'destroy']);
});
5. Testing API Authentication dengan Tools Seperti Postman
Setelah membuat controller dan routes, saatnya untuk melakukan pengujian API kita. Salah satu tools yang populer untuk testing API adalah Postman.
Langkah-langkah Pengujian dengan Postman:
-
Install Postman: Jika kamu belum memiliki Postman, unduh dan install dari https://www.postman.com/.
-
Register User:
-
Buat request
POSTke endpoint/api/register. -
Pada tab
Body, pilihrawdan formatJSON. -
Masukkan data registrasi (
name,email,password) dalam format JSON:{ "name": "John Doe", "email": "[email protected]", "password": "password123" } -
Klik
Send. Kamu akan menerima response JSON yang berisiaccess_tokendantoken_type. Simpanaccess_tokenini, karena akan kita gunakan untuk mengakses route yang dilindungi.
-
-
Login User:
-
Buat request
POSTke endpoint/api/login. -
Pada tab
Body, pilihrawdan formatJSON. -
Masukkan data login (
email,password) dalam format JSON:{ "email": "[email protected]", "password": "password123" } -
Klik
Send. Kamu akan menerima response JSON yang berisiaccess_tokendantoken_type. Simpanaccess_tokenini.
-
-
Akses Route yang Dilindungi (Contoh:
/api/me):- Buat request
GETke endpoint/api/me. - Pada tab
Headers, tambahkan headerAuthorizationdengan valueBearer <access_token>, ganti<access_token>dengan token yang kamu dapatkan dari proses registrasi atau login. - Klik
Send. Kamu akan menerima response JSON yang berisi data user (jika token valid).
- Buat request
-
Logout User:
- Buat request
POSTke endpoint/api/logout. - Pada tab
Headers, tambahkan headerAuthorizationdengan valueBearer <access_token>, ganti<access_token>dengan token yang kamu dapatkan dari proses registrasi atau login. - Klik
Send. Kamu akan menerima response JSON yang berisi pesan sukses logout.
- Buat request
Dengan Postman, kamu bisa dengan mudah menguji setiap endpoint API kamu dan memastikan sistem autentikasi berjalan dengan benar.
6. Stateful Authentication dengan Laravel Sanctum (CSRF Protection)
Laravel Sanctum tidak hanya mendukung autentikasi stateless (berbasis token), tetapi juga stateful (berbasis session) untuk aplikasi yang dijalankan di browser. Autentikasi stateful menawarkan perlindungan CSRF (Cross-Site Request Forgery) yang penting untuk keamanan aplikasi web.
Bagaimana cara kerjanya?
- Sanctum’s SPA Route: Sanctum menyediakan sebuah route khusus (biasanya
/sanctum/csrf-cookie) yang digunakan untuk menetapkan cookie CSRF pada browser. - JavaScript Client: Aplikasi SPA (misalnya menggunakan React, Vue.js, atau Angular) harus melakukan request ke route ini sebelum mengirimkan request authenticated ke API.
- CSRF Token: Response dari route
/sanctum/csrf-cookieakan menyertakan cookie CSRF (biasanya bernamaXSRF-TOKEN). - Automatic Injection: Axios (library HTTP client yang populer untuk JavaScript) secara otomatis akan menyertakan nilai cookie
XSRF-TOKENke dalam headerX-XSRF-TOKENuntuk setiap request subsequent. - Server Verification: Laravel Sanctum memverifikasi keberadaan dan validitas header
X-XSRF-TOKENpada setiap request authenticated. Jika tidak ada atau tidak valid, request akan ditolak.
Langkah-langkah Implementasi Stateful Authentication:
-
Konfigurasi CORS: Pastikan CORS (Cross-Origin Resource Sharing) dikonfigurasi dengan benar untuk mengizinkan aplikasi SPA kamu mengakses API. Edit
config/cors.phpdan sesuaikanallowed_originssesuai dengan domain aplikasi SPA kamu.'paths' => ['api/*', 'sanctum/csrf-cookie'], // Tambahkan 'sanctum/csrf-cookie' 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:3000'], // Ganti dengan domain SPA kamu 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'supports_credentials' => true, // Penting untuk cookie 'max_age' => 0, -
Pastikan
EnsureFrontendRequestsAreStatefulMiddleware Ada: MiddlewareEnsureFrontendRequestsAreStatefulbertanggung jawab untuk memastikan bahwa request dari frontend diperlakukan sebagai stateful. Middleware ini biasanya sudah ada diapp/Http/Kernel.php, pada$middlewareGroupsbagian ‘api’:'api' => [ AppHttpMiddlewareEncryptCookies::class, IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class, IlluminateSessionMiddlewareStartSession::class, IlluminateViewMiddlewareShareErrorsFromSession::class, AppHttpMiddlewareVerifyCsrfToken::class, // Pastikan middleware ini ada AppHttpMiddlewareTrimStrings::class, IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull::class, AppHttpMiddlewareTrustProxies::class, LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful::class, ],Jika belum ada, kamu bisa membuatnya dengan
php artisan make:middleware EnsureFrontendRequestsAreStatefuldan menempatkannya di$middlewareGroups. Isinya harus seperti ini:<?php namespace AppHttpMiddleware; use Closure; use IlluminateHttpRequest; use SymfonyComponentHttpFoundationResponse; use LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful as SanctumMiddleware; class EnsureFrontendRequestsAreStateful extends SanctumMiddleware { /** * Get the cookies that should be considered stateful. * * @param IlluminateHttpRequest $request * @return array<int, string> */ public static function stateful(Request $request): array { return config('sanctum.stateful', []); } } -
Request CSRF Cookie dari Frontend: Sebelum melakukan request authenticated, aplikasi SPA kamu harus mengirimkan request
GETke endpoint/sanctum/csrf-cookie. Ini akan menetapkan cookie CSRF yang diperlukan.Contoh menggunakan Axios:
import axios from 'axios'; axios.get('/sanctum/csrf-cookie').then(response => { // Setelah mendapatkan CSRF cookie, lakukan request authenticated axios.get('/api/me', { headers: { 'X-Requested-With': 'XMLHttpRequest' // Penting untuk stateful } }).then(response => { console.log(response.data); }); });
Penting: Pastikan kamu menambahkan header X-Requested-With: XMLHttpRequest pada request authenticated dari frontend. Ini memberitahu Laravel bahwa request berasal dari JavaScript dan harus diperlakukan sebagai stateful.
Dengan implementasi stateful authentication ini, aplikasi kamu terlindungi dari serangan CSRF.
7. Konfigurasi Tambahan: Token Expiration dan Revocation
Laravel Sanctum memungkinkan kamu mengontrol masa berlaku token API dan melakukan revocation (pencabutan) token secara manual.
Token Expiration:
Secara default, token API di Laravel Sanctum tidak memiliki masa berlaku. Artinya, token akan tetap valid sampai user melakukan logout atau token dicabut secara manual. Kamu bisa mengimplementasikan token expiration dengan menggunakan custom logic. Contohnya:
-
Tambahkan Kolom
expires_atke Tabelpersonal_access_tokens:php artisan make:migration add_expires_at_to_personal_access_tokens --table=personal_access_tokensEdit file migrasi yang baru dibuat (misalnya
database/migrations/2023_10_27_100000_add_expires_at_to_personal_access_tokens.php) dan tambahkan kode berikut:<?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::table('personal_access_tokens', function (Blueprint $table) { $table->timestamp('expires_at')->nullable(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('personal_access_tokens', function (Blueprint $table) { $table->dropColumn('expires_at'); }); } };Jalankan migrasi:
php artisan migrate -
Modifikasi
AuthController(Login dan Register): Tambahkan logic untuk menetapkan nilaiexpires_atsaat membuat token.public function register(Request $request) { // ... kode validasi ... $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); $token = $user->createToken('auth_token', ['*'], now()->addDays(7))->plainTextToken; // Token berlaku selama 7 hari return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', ]); } public function login(Request $request) { // ... kode validasi ... $user = User::where('email', $request->email)->first(); // ... kode validasi credential ... $token = $user->createToken('auth_token', ['*'], now()->addDays(7))->plainTextToken; // Token berlaku selama 7 hari return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', ]); }Perhatikan perubahan pada
createToken(): kita menambahkan parameter ketiga, yaitunow()->addDays(7). Ini menetapkan masa berlaku token selama 7 hari. Kamu bisa menyesuaikan nilai ini sesuai kebutuhan. Perhatikan bahwa, dengan menambahkan parameter ketiga, kamu juga harus menambahkan parameter kedua, yaituabilities. Kami menggunakan['*']untuk memberikan semua abilities pada token. -
Buat Middleware untuk Memeriksa Token Expiration:
php artisan make:middleware CheckTokenExpirationEdit
app/Http/Middleware/CheckTokenExpiration.phpdan tambahkan kode berikut:<?php namespace AppHttpMiddleware; use Closure; use IlluminateHttpRequest; use SymfonyComponentHttpFoundationResponse; use CarbonCarbon; class CheckTokenExpiration { /** * Handle an incoming request. * * @param IlluminateHttpRequest $request * @param Closure(IlluminateHttpRequest): (SymfonyComponentHttpFoundationResponse) $next */ public function handle(Request $request, Closure $next): Response { $token = $request->bearerToken(); if ($token) { $personalAccessToken = $request->user()->tokens()->where('token', hash('sha256', $token))->first(); if ($personalAccessToken && $personalAccessToken->expires_at && Carbon::parse($personalAccessToken->expires_at)->isPast()) { $personalAccessToken->delete(); return response()->json(['message' => 'Token has expired'], 401); } } return $next($request); } } -
Register Middleware di
Kernel.php: Bukaapp/Http/Kernel.phpdan tambahkan middlewareCheckTokenExpirationke$routeMiddleware.protected $routeMiddleware = [ 'auth' => AppHttpMiddlewareAuthenticate::class, 'auth.basic' => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class, 'cache.headers' => IlluminateHttpMiddlewareSetCacheHeaders::class, 'can' => IlluminateAuthMiddlewareAuthorize::class, 'guest' => AppHttpMiddlewareRedirectIfAuthenticated::class, 'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class, 'signed' => IlluminateRoutingMiddlewareValidateSignature::class, 'CheckTokenExpiration' => AppHttpMiddlewareCheckTokenExpiration::class, // Tambahkan ini ]; -
Gunakan Middleware di
routes/api.php:Route::middleware(['auth:sanctum', 'CheckTokenExpiration'])->group(function () { Route::get('/me', [AuthController::class, 'me']); Route::post('/logout', [AuthController::class, 'logout']); });
Token Revocation:
Token revocation memungkinkan kamu mencabut token secara manual, misalnya ketika user mengganti password atau perangkatnya hilang. Kita sudah melihat contoh revocation di method logout() pada AuthController:
public function logout(Request $request)
{
$request->user()->currentAccessToken()->delete();
return response()->json([
'message' => 'Successfully logged out'
]);
}
Kode ini menghapus token yang sedang aktif untuk user yang melakukan request. Kamu juga bisa mencabut token tertentu berdasarkan ID:
use LaravelSanctumPersonalAccessToken;
public function revokeToken(Request $request, $tokenId)
{
$token = PersonalAccessToken::findToken($tokenId);
if ($token && $token->tokenable_id == $request->user()->id) {
$token->delete();
return response()->json(['message' => 'Token revoked successfully']);
}
return response()->json(['message' => 'Token not found or unauthorized'], 404);
}
Pastikan untuk menambahkan route yang dilindungi untuk memanggil method revokeToken().
8. Menangani Multiple Token dan Abilities (Scopes)
Laravel Sanctum memungkinkan user untuk memiliki lebih dari satu token API. Ini berguna jika kamu ingin memberikan akses yang berbeda ke berbagai aplikasi atau layanan. Misalnya, aplikasi mobile mungkin membutuhkan akses yang berbeda dari aplikasi web. Selain itu, kita juga bisa mengatur abilities (dahulu dikenal sebagai scopes) untuk setiap token. Abilities mendefinisikan izin apa saja yang dimiliki oleh sebuah token.
Membuat Multiple Token:
Kita sudah melihat cara membuat token di method register() dan login() pada AuthController. Setiap kali method ini dipanggil, sebuah token baru akan dibuat untuk user. User bisa memiliki beberapa token yang aktif sekaligus.
Menggunakan Abilities (Scopes):
Saat membuat token, kita bisa menentukan abilities apa saja yang dimiliki oleh token tersebut. Contohnya:
$token = $user->createToken('app-token', ['posts:create', 'posts:update']);
Kode ini membuat token dengan nama app-token yang memiliki dua abilities: posts:create dan posts:update. Artinya, token ini hanya bisa digunakan untuk membuat dan mengupdate posts.
Memverifikasi Abilities:
Untuk memverifikasi apakah sebuah token memiliki ability tertentu, kita bisa menggunakan method tokenCan() pada $request->user():
Route::post('/posts', function (Request $request) {
if ($request->user()->tokenCan('posts:create')) {
// User memiliki izin untuk membuat posts
// ... kode untuk membuat posts ...
} else {
return response()->json(['message' => 'Unauthorized'], 403);
}
})->middleware('auth:sanctum');
Kita juga bisa menggunakan middleware abilities untuk melindungi route:
Route::post('/posts', function (Request $request) {
// ... kode untuk membuat posts ...
})->middleware(['auth:sanctum', 'abilities:posts:create']);
Dengan menggunakan multiple token dan abilities, kamu bisa mengontrol akses ke API kamu dengan lebih granular.
9. Kesimpulan: Mengamankan API Laravel dengan Laravel Sanctum
Selamat! Kamu telah berhasil mempelajari cara membuat sistem keamanan API dengan Laravel Sanctum. Kita telah membahas:
- Apa itu Laravel Sanctum dan mengapa kita menggunakannya.
- Cara menginstal dan mengkonfigurasi Laravel Sanctum.
- Cara membuat controller dan routes untuk autentikasi (registrasi, login, logout).
- Cara mengamankan routes dengan middleware
auth:sanctum. - Cara testing API authentication dengan Postman.
- Cara mengimplementasikan stateful authentication (CSRF protection).
- Cara mengkonfigurasi token expiration dan revocation.
- Cara menangani multiple token dan abilities (scopes).
Laravel Sanctum adalah tool yang powerful dan mudah digunakan untuk mengamankan API Laravel kamu. Dengan mengikuti tutorial ini, kamu sudah memiliki dasar yang kuat untuk membangun API yang aman dan terpercaya. Jangan ragu untuk bereksperimen dan menyesuaikan kode sesuai dengan kebutuhan proyek kamu. Selamat mencoba!
10. Sumber Daya Tambahan dan Referensi
Untuk memperdalam pemahaman kamu tentang Laravel Sanctum, berikut adalah beberapa sumber daya tambahan dan referensi yang bisa kamu gunakan:
- Dokumentasi Resmi Laravel Sanctum: https://laravel.com/docs/10.x/sanctum
- Laravel News – Laravel Sanctum: https://laravel-news.com/laravel-sanctum
- Tutorial Laracasts tentang Laravel Sanctum: (Cari di Laracasts untuk tutorial terbaru karena konten berubah seiring waktu)
- Berbagai artikel dan tutorial di Medium dan Dev.to tentang Laravel Sanctum: (Cari dengan keyword “Laravel Sanctum tutorial”)
Dengan mempelajari sumber daya ini, kamu akan semakin ahli dalam menggunakan Laravel Sanctum untuk mengamankan API Laravel kamu.

