Konsep autentikasi

Perbedaan session dan token, serta peran guard dan provider.

Daftar isi

Autentikasi adalah proses membuktikan identitas pengguna yang mengirimkan sebuah permintaan, sedangkan otorisasi menentukan hal yang boleh dilakukan oleh identitas tersebut. Topik ini membahas dua pendekatan autentikasi pada aplikasi web, yaitu session dan token, lalu menjelaskan cara Laravel memetakan keduanya melalui guard dan provider pada berkas config/auth.php. Setelah topik ini dibaca, setiap bagian konfigurasi autentikasi bawaan dapat dipahami, dan pilihan antara session atau token dapat ditentukan secara sadar sesuai kebutuhan aplikasi.

Dua cara mengenali pengguna#

Aplikasi web mengenali pengguna yang sudah login melalui dua pendekatan utama, yaitu session dan token. Pada pendekatan session, status login disimpan pada sisi server, sedangkan browser hanya menyimpan cookie yang berisi pengenal session. Cookie itu dikirim otomatis pada setiap permintaan berikutnya, sehingga server dapat mencari kembali status login yang tersimpan. Pendekatan ini lazim digunakan untuk aplikasi yang antarmukanya dirender di server, misalnya aplikasi yang dibangun dengan Blade.

Pendekatan token bekerja sebaliknya. Server tidak menyimpan status login sama sekali, sehingga klien wajib mengirimkan token pada setiap permintaan, biasanya melalui header Authorization: Bearer <token>. Model tanpa status ini disebut stateless dan menjadi pilihan utama untuk API yang dikonsumsi aplikasi mobile atau frontend terpisah. Untuk kebutuhan tersebut, Laravel menyediakan paket Sanctum yang membuat token API, sedangkan seluruh contoh pada aplikasi catatan menggunakan pendekatan session.

Perbedaan keduanya dirangkum pada tabel berikut.

AspekSessionToken
Penyimpanan statusServer, pada tabel atau berkas sessionKlien
Kredensial yang dikirimPengenal session di dalam cookieToken pada header Authorization
Beban serverMenyimpan dan mencari status loginTidak menyimpan status
Penggunaan lazimAplikasi web dengan BladeAPI dan aplikasi mobile

Guard dan provider#

Laravel mengatur autentikasi melalui dua konsep yang dideklarasikan pada berkas config/auth.php. Guard adalah mekanisme yang menentukan cara pengguna diautentikasi, misalnya dengan memeriksa session atau dengan membaca token. Provider menentukan sumber data pengguna yang diperiksa oleh guard, misalnya tabel users yang diakses melalui model Eloquent. Keduanya dideklarasikan berpasangan, sehingga satu guard selalu merujuk ke satu provider.

php Bagian inti berkas config/auth.php
// tidak-dijalankan
'defaults' => [
    'guard' => env('AUTH_GUARD', 'web'),
    'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
],

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
],

Konfigurasi di atas terbaca sebagai berikut: guard bawaan bernama web menggunakan driver session, dan driver session itu mengambil pengguna dari provider bernama users, sedangkan provider users mengakses tabel users melalui kelas App\Models\User. Efek konfigurasi ini dapat diperiksa tanpa membuka berkasnya sama sekali dengan perintah config:show.

bash
# menampilkan konfigurasi autentikasi yang aktif
cd ~/aplikasi-catatan
php artisan config:show auth
text Keluaran
  auth .......................................................................
  defaults ⇁ guard ....................................................... web
  defaults ⇁ passwords ................................................. users
  guards ⇁ web ⇁ driver .............................................. session
  guards ⇁ web ⇁ provider .............................................. users
  guards ⇁ sanctum ⇁ driver .......................................... sanctum
  guards ⇁ sanctum ⇁ provider ........................................... null
  providers ⇁ users ⇁ driver ........................................ eloquent
  providers ⇁ users ⇁ model .................................. App\Models\User
  passwords ⇁ users ⇁ provider ......................................... users
  passwords ⇁ users ⇁ table ............................ password_reset_tokens
  passwords ⇁ users ⇁ expire .............................................. 60
  passwords ⇁ users ⇁ throttle ............................................ 60
  password_timeout ..................................................... 10800

Entri guards ⇁ sanctum pada keluaran itu ditambahkan oleh service provider milik paket Sanctum yang terpasang pada proyek uji, sehingga keluaran pada lingkungan tanpa Sanctum tidak memuatnya.

Alur autentikasi session#

Cara kerja guard session pada satu permintaan dapat dirangkum sebagai berikut. Ketika proses login berhasil, guard menyimpan pengenal pengguna ke dalam session, dan permintaan berikutnya membaca pengenal itu kembali dari session. Apabila pengenalnya ada, guard meminta provider untuk mengambil model pengguna dari database, lalu model tersebut tersedia di seluruh aplikasi melalui Auth::user(). Diagram berikut memperlihatkan pembagian peran tersebut.

PermintaanHTTP + cookieGuard "web"driver sessionProvider "users"driver eloquentModel Usertabel usersGuard menentukan cara memeriksa, provider menentukan sumber data pengguna
Peran guard dan provider pada satu permintaan
Status login pada aplikasi contoh dapat diperiksa langsung di database karena driver session bawaan Laravel adalah database. Struktur tabel sessions berikut memperlihatkan kolom user_id yang menghubungkan sebuah session dengan baris pengguna di tabel users, serta kolom payload yang menyimpan data session.

bash
# melihat struktur tabel sessions yang menampung status login
cd ~/aplikasi-catatan
sqlite3 database/database.sqlite '.schema sessions'
text Keluaran
CREATE TABLE IF NOT EXISTS "sessions" ("id" varchar not null, "user_id" integer, "ip_address" varchar, "user_agent" text, "payload" text not null, "last_activity" integer not null, primary key ("id"));
CREATE INDEX "sessions_user_id_index" on "sessions" ("user_id");
CREATE INDEX "sessions_last_activity_index" on "sessions" ("last_activity");

Rangkaian konsep guard dan provider tersebut diwujudkan oleh kelas-kelas konkret di dalam Laravel. Kelas yang aktif dapat diperiksa dengan menanyakan nama kelas objek yang dikembalikan Auth::guard().

bash
# memeriksa kelas guard dan provider yang aktif
cd ~/aplikasi-catatan
php artisan tinker --execute='echo get_class(Auth::guard("web"))."\n"; echo get_class(Auth::guard("web")->getProvider())."\n"; echo Auth::guard("web")->getProvider()->getModel()."\n";'
text Keluaran
Illuminate\Auth\SessionGuard
Illuminate\Auth\EloquentUserProvider
App\Models\User

Keluaran tersebut menegaskan bahwa guard web diwujudkan oleh kelas SessionGuard, sedangkan provider users diwujudkan oleh EloquentUserProvider yang mengambil data pengguna dari model App\Models\User.

Kesalahan umum#

Kesalahan pertama adalah menganggap isi session tersimpan di dalam browser. Yang tersimpan di browser hanya cookie berisi pengenal session, sedangkan datanya berada di server, yaitu pada tabel sessions pada aplikasi contoh. Memperbesar isi session berarti menambah beban penyimpanan server, bukan ukuran cookie.

Kesalahan kedua adalah menggunakan Auth::attempt() pada konteks API. Metode tersebut bekerja melalui guard session, sehingga pencarian status login dilakukan pada session yang tidak pernah ada ketika permintaan datang dari aplikasi mobile. Untuk API, gunakan guard berbasis token, misalnya personal access token yang diterbitkan paket Sanctum.

Kesalahan ketiga adalah menggunakan Auth::user() tanpa memeriksa keberadaannya. Metode itu mengembalikan null ketika pengunjung belum login, sehingga pemanggilan properti atau metode pada hasilnya langsung berakhir dengan error. Pemeriksaan Auth::check() menyatakan ada tidaknya pengguna yang terautentikasi, sedangkan rute yang wajib login sebaiknya dilindungi middleware auth agar pemeriksaan itu tidak perlu ditulis berulang.

Ringkasan#

  • Session menyimpan status login di server dan mengandalkan cookie berisi pengenal, sedangkan token membawa kredensial pada setiap permintaan sehingga server bersifat stateless.
  • Guard menentukan cara pengguna diautentikasi, sedangkan provider menentukan sumber data pengguna, dan keduanya dideklarasikan pada config/auth.php.
  • Konfigurasi aktif dapat diperiksa dengan php artisan config:show auth, dan kelas yang mewujudkan guard serta provider dapat dilihat melalui Auth::guard().
  • Pada driver session database, status login tersimpan di tabel sessions dengan kolom user_id yang merujuk ke tabel users.

Referensi#