Laravel Sanctum adalah package autentikasi ringan yang menangani dua skenario paling umum dalam aplikasi modern: token-based authentication untuk mobile app / third-party API consumers, dan cookie-based session authentication untuk SPA (Single Page Application). Artikel ini membahas implementasi keduanya secara lengkap.
Kapan Memilih Sanctum vs Passport?
Laravel punya dua package autentikasi utama:
- Sanctum — Ringan, untuk aplikasi yang Anda sendiri yang buat (first-party). Cocok untuk SPA + mobile app milik sendiri.
- Passport — Full OAuth2 server, untuk skenario third-party authorization (seperti "Login with App X"). Lebih kompleks dan berat.
Untuk 90% kasus, Sanctum sudah lebih dari cukup.
Instalasi dan Setup
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Tambahkan HasApiTokens trait ke model User:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
Skenario 1: Token Auth untuk Mobile / API Client
Cocok untuk aplikasi mobile (Flutter, React Native) atau klien API eksternal.
Login — Issue Token
class AuthController extends Controller
{
public function login(LoginRequest $request): JsonResponse
{
if (! Auth::attempt($request->only('email', 'password'))) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$user = Auth::user();
$token = $user->createToken(
name: $request->device_name ?? 'api',
abilities: ['*'],
expiresAt: now()->addDays(30),
)->plainTextToken;
return response()->json([
'user' => new UserResource($user),
'token' => $token,
]);
}
public function logout(Request $request): JsonResponse
{
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out']);
}
}
Protect Routes
// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn (Request $r) => new UserResource($r->user()));
Route::apiResource('/posts', PostController::class);
});
Penggunaan dari Client
// Header setiap request
Authorization: Bearer 1|abc123xyz...
Skenario 2: SPA Authentication dengan Cookies
Untuk SPA Vue/React yang di-serve dari domain yang sama atau subdomain. Lebih aman dari token karena tidak menyimpan token di localStorage (rentan XSS).
Setup CORS dan Session
// config/sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
Flow SPA Auth
- SPA memanggil
GET /sanctum/csrf-cookieuntuk mendapatkan CSRF token - SPA mengirim POST ke
/logindengan credentials - Laravel set session cookie, SPA sudah authenticated
- Setiap request berikutnya otomatis terautentikasi via cookie
// Axios setup di Vue/React
axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;
// Login
await axios.get('/sanctum/csrf-cookie');
await axios.post('/login', { email, password });
Token Abilities (Scope)
Sanctum mendukung pembatasan kemampuan token:
// Issue token dengan abilities terbatas
$token = $user->createToken('readonly-token', ['posts:read', 'comments:read']);
// Check di controller
if (! $request->user()->tokenCan('posts:write')) {
abort(403, 'Token tidak memiliki izin write');
}
Best Practices Keamanan
- Selalu set expiration time pada token — jangan buat token yang tidak pernah expired
- Hapus semua token saat user ganti password:
$user->tokens()->delete() - Gunakan HTTPS di production — token di header HTTP bisa disadap tanpa TLS
- Untuk SPA, gunakan cookie-based auth (lebih aman dari localStorage)
- Implementasikan rate limiting di route auth untuk mencegah brute force
Rate Limiting
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->throttleApi();
})
// Atau custom di routes
Route::middleware(['auth:sanctum', 'throttle:60,1'])->group(function () {
// ...
});
Sanctum menyederhanakan autentikasi API tanpa overhead OAuth2 penuh. Untuk aplikasi yang Anda sendiri yang control client-nya, Sanctum adalah pilihan yang tepat dan cukup aman jika diimplementasikan dengan benar.