Validasi menjaga kualitas data, tetapi belum menjawab siapa yang berhak mengirim request. Di aplikasi web, pertanyaan itu diselesaikan session: cookie terpasang di browser, server mengenali pengunjung di setiap halaman. Dunia API tidak semudah itu — client bisa berupa aplikasi mobile, skrip server, atau layanan pihak ketiga yang tidak punya browser sama sekali. Chapter ini memetakan masalah ini secara konseptual dan menuntun kita memilih strategi autentikasi API di Laravel, lengkap dengan wiring auth:sanctum yang teruji. Implementasi token dari nol menyusul di chapter Token Authentication .

Kenapa Session Gagal untuk API #

Autentikasi berbasis session bertumpu pada tiga hal yang tidak dimiliki client API. Pertama, session menyimpan keadaan login di server — melanggar statelessness yang kita sepakati di awal section. Kedua, session bekerja lewat cookie yang otomatis dikirim browser; aplikasi mobile dan kode server-side tidak punya mekanisme itu secara natural. Ketiga, form web dilindungi middleware CSRF yang membaca token dari session — lingkaran yang tidak bisa diikuti client tanpa session.

| Aspek | Session (web) | Token (API) | | | | | | Identitas disimpan | Server (session store) | Client (menyimpan token) | | Dikirim lewat | Cookie otomatis | Header Authorization manual | | Keadaan | Stateful | Stateless | | Perlindungan ekstra | CSRF middleware | Tidak perlu CSRF | | Klien cocok | Browser | Mobile, SPA, server-to-server |

Kesimpulannya bukan “session jahat” — keduanya sekadar alat untuk audiens berbeda. Bahkan keduanya bisa dipakai berdampingan: halaman admin web memakai session, endpoint data memakai token, dalam satu aplikasi Laravel.

Taksonomi Pendekatan Token #

Semua strategi token API pada dasarnya menjawab satu pertanyaan: bagaimana server memverifikasi keaslian client? Tiga keluarga besar menjawabnya dengan cara berbeda:

| Pendekatan | Cara kerja | Kekuatan | Kelemahan | | | | | | | Random token | Server membuat string acak, simpan hash-nya di database, client mengirim ulang tiap request | Sederhana, bisa dicabut kapan saja | Butuh query database tiap request | | JWT | Data identitas ditandatangani secara kriptografis, client membawa sendiri klaimnya | Stateless murni, tidak butuh penyimpanan | Sulit dicabut sebelum kedaluwarsa | | OAuth 2.0 | Alur delegasi akses lewat authorization server | Standar industri untuk pihak ketiga | Kompleks, overkill untuk API sendiri |

Random token adalah titik masuk terbaik untuk memahami mekanismenya — kita akan membangunnya secara manual di chapter Token Authentication , lalu menyadari mengapa paket resmi menyingkat pekerjaan itu.

Sanctum: Jawaban Resmi Laravel #

Laravel Sanctum adalah paket resmi yang menyediakan token API bergaya random-token dengan penyimpanan database, plus satu trik cerdas: Sanctum juga bisa mengautentikasi SPA first-party lewat cookie session dari daftar stateful domains. Untuk client eksternal (mobile, server pihak ketiga), Sanctum mengeluarkan personal access token yang dikirim sebagai Bearer token. Token ini disimpan dalam bentuk hash di tabel personal_access_tokens — kebocoran database tidak langsung membocorkan token yang bisa dipakai.

Karena pembahasan Sanctum cukup dalam untuk berdiri sendiri, Section ini menempatkannya terpisah — konsep dasar token di sini, implementasinya menyusul di chapter Token Authentication dan section Laravel Sanctum .

Guard: auth:api vs auth:sanctum #

Laravel menyebut mekanisme autentikasi sebagai guard, dan file config/auth.php menunjukkan peta kita: guard bawaan satu-satunya bernama web dengan driver session. Tidak ada guard bernama api di aplikasi baru — berbeda dengan Laravel versi lama yang menyediakannya dengan driver token.

Konsekuensinya nyata saat kita menulis middleware. auth:api hanya bekerja bila kita mendefinisikan guard api sendiri; tanpa definisi itu, Laravel bahkan menolak request dengan server error — kita uji langsung dan hasilnya HTTP 500. Adapun auth:sanctum bekerja sejak instalasi karena paket Sanctum mendaftarkan guard sanctum secara otomatis ke framework. Jadi untuk API berbasis token di Laravel modern, pilihan pragmatisnya jelas: middleware auth:sanctum.

Melindungi Route dan Bentuk Error 401 #

Sekarang bagian wiring. Trait HasApiTokens dipasang di model User agar pengguna bisa memiliki token, lalu route dilindungi middleware auth:sanctum:

php
<?php

// app/Models/User.php (cuplikan)

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}
php
<?php

// routes/api.php (di dalam group prefix v1)

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/profil', fn (Request $request) => [
    'nama' => $request->user()->name,
    'email' => $request->user()->email,
    'token_abilities' => $request->user()->currentAccessToken()->abilities,
])->middleware('auth:sanctum');

Token dibuat sekali dari sisi aplikasi — misalnya saat login — lewat $user->createToken('mobile-budi', ['posts:read']). Client kemudian menyimpan nilai token tersebut dan mengirimnya di setiap request sebagai header Authorization: Bearer <token>. Kita buktikan keduanya dari runner:

Output yang Dihasilkan:

text
### GET /api/v1/profil tanpa token → HTTP 401
{
    "message": "Unauthenticated."
}

### GET /api/v1/profil dengan Bearer token → HTTP 200
{
    "nama": "Budi",
    "email": "[email protected]",
    "token_abilities": [
        "posts:read"
    ]
}

Bentuk 401 ini penting dihafal: satu kunci message dengan nilai "Unauthenticated." — ringkas, deterministik, dan mudah dikenali client untuk mengalihkan pengguna ke layar login. Sedangkan pemanggilan yang sah membuat $request->user() terisi otomatis, dan currentAccessToken() memaparkan abilities yang melekat pada token tersebut. Di database, baris token menyimpan metadata lengkap tanpa nilai aslinya:

text
metadata token di tabel personal_access_tokens:
{
    "id": 1,
    "name": "mobile-budi",
    "tokenable_id": 1,
    "abilities": ["posts:read"],
    "last_used_at": "2026-01-02 09:00:00"
}

Peta autentikasi API kini lengkap: session kita tinggalkan di dunia web, token menjadi bahasa penghubung, dan Sanctum menyediakan implementasinya dengan guard siap pakai. Tetapi memakai Sanctum tanpa memahami mekanisme di baliknya membuat kita bergantung pada sihir — chapter berikutnya membedah sihir itu dengan membangun autentikasi bearer token secara manual di Token Authentication . Dokumentasi resmi Sanctum tersedia di dokumentasi sanctum .