Kamu berhasil login ke aplikasi Laravel. Session atau token sudah valid, dan sistem tahu siapa kamu. Namun, setelah login, kamu justru dapat membuka halaman invoice milik pelanggan lain hanya dengan mengganti angka ID di URL dari /invoice/101 menjadi /invoice/102. Login hanya membuktikan siapa kamu. Pertanyaan yang belum terjawab adalah: apakah kamu diizinkan untuk melihat data itu?
Ini adalah inti dari Authorization (AuthZ) atau otorisasi. Authentication menjawab "Siapa kamu?", sementara Authorization menjawab "Apa yang boleh kamu lakukan?". Tanpa otorisasi yang tepat, aplikasi kamu mungkin sudah melindungi pintu masuk, tetapi semua ruangan di dalamnya terbuka untuk siapa saja yang berhasil masuk.
Apa itu Authorization (AuthZ)?
Authorization (AuthZ), dalam bahasa Indonesia disebut otorisasi, adalah proses menentukan apakah identitas yang telah terverifikasi memiliki hak akses untuk melakukan suatu tindakan pada sumber daya tertentu. Singkatnya, AuthZ menjawab pertanyaan: "Apakah subjek X diizinkan melakukan tindakan Y pada objek Z?".
Hasil dari proses otorisasi adalah keputusan biner: Permit (diizinkan) atau Deny (ditolak). Jika permintaan ditolak, sistem biasanya mengembalikan respons HTTP 403 Forbidden. Ini berbeda dari gagal autentikasi, yang biasanya menghasilkan 401 Unauthorized.
Penting untuk dipahami bahwa Authorization tidak bisa berjalan sendirian. Sebelum sistem mengevaluasi apakah kamu boleh mengakses sebuah resource, identitas kamu harus diverifikasi terlebih dahulu melalui Authentication. Jadi alurnya adalah: Autentikasi terlebih dahulu, baru otorisasi setelahnya. Authentication terjadi di lapisan paling depan, sementara Authorization bekerja di lapisan aplikasi setelah identitas pengguna diketahui dari session atau token.
Mengapa Authorization penting? Karena login saja tidak cukup untuk melindungi data. Sebuah aplikasi mungkin sudah memiliki halaman login yang aman, tetapi jika tidak ada pemeriksaan hak akses, pengguna yang login masih dapat mencoba mengakses data milik pengguna lain, membuka halaman admin, atau memanggil fungsi yang seharusnya terbatas. Authorization adalah lapisan keamanan kedua yang melengkapi Authentication.
Untuk memahami perbedaan keduanya secara lebih detail, kamu dapat membaca pengertian Authentication dan cara kerjanya, serta perbedaan Authentication dan Authorization.
Sebagai analogi sederhana, bayangkan kamu masuk ke bangunan kantor. Security di pintu masuk memeriksa KTP kamu — ini adalah Authentication. Setelah kamu masuk, kartu akses kantor menentukan ruangan mana yang boleh kamu masuki, seperti ruang arsip atau ruang server — ini adalah Authorization. Kartu itu tidak membuktikan siapa kamu, tetapi menentukan apa yang boleh kamu lakukan setelah identitas kamu diketahui.
Cara Kerja Authorization (Alur Dasar)
Proses otorisasi biasanya berlangsung dalam lima langkah berikutnya setelah pengguna melakukan request ke server:
Pertama, pengguna melakukan login melalui Authentication. Server memverifikasi kredensial dan menerbitkan bukti identitas, biasanya dalam bentuk session cookie atau token yang berisi klaim (claims) seperti user ID, role, atau permission.
Kedua, pengguna mengirim HTTP request ke resource tertentu, menyertakan bukti identitas tersebut, misalnya melalui cookie atau header Authorization: Bearer <token>.
Ketiga, server memverifikasi bukti identitas (Authentication) dan mengekstrak identitas pengguna, termasuk role, permission, dan claims yang terkait.
Keempat, lapisan Authorization mengevaluasi aturan akses. Sistem memeriksa apakah pengguna dengan role atau permission tersebut diizinkan melakukan tindakan X pada resource Y. Pemeriksaan ini bisa dilakukan melalui query database, seperti memastikan user_id pemilik resource sama dengan pengguna yang login, atau melalui Laravel Policy yang telah kamu definisikan.
Terakhir, jika diizinkan, sistem mengeksekusi business logic dan mengembalikan respons 200 OK bersama data yang diminta. Jika tidak diizinkan, sistem mengembalikan 403 Forbidden.
Alur ini selalu terjadi di sisi backend. Frontend hanya dapat menyembunyikan tombol atau menu berdasarkan role, tetapi itu bukan otorisasi yang nyata. Keputusan akhir harus selalu dibuat di server.
Model Otorisasi (Authorization Models)
Ada beberapa model otorisasi yang umum digunakan, dan masing-masing memiliki karakteristik serta kasus penggunaan yang berbeda. Pemilihan model tergantung pada kompleksitas aplikasi dan kebutuhan kontrol akses kamu.
RBAC (Role-Based Access Control)
RBAC adalah model di mana hak akses dikelompokkan per role. Sebuah role, seperti admin, editor, atau viewer, memiliki kumpulan permission. Pengguna kemudian diassign ke satu atau lebih role. Misalnya, dalam sebuah CMS, role admin dapat membuat, mengedit, dan menghapus artikel; role editor hanya boleh mengedit; sementara role viewer hanya boleh membaca.
Keuntungan RBAC adalah kesederhanaan dan kemudahan pengelolaannya, terutama untuk aplikasi skala kecil hingga menengah. Namun, RBAC rentan terhadap masalah yang disebut role explosion. Semakin spesifik aturan akses yang diperlukan, semakin banyak role yang harus kamu buat, sehingga sulit dikelola pada skala besar.
ABAC (Attribute-Based Access Control) / PBAC
ABAC mengevaluasi akses secara dinamis berdasarkan atribut. Atribut dapat datang dari subjek (pengguna), resource, tindakan, dan lingkungan, seperti waktu, IP address, atau perangkat yang digunakan. Misalnya, sebuah dokumen medis hanya dapat diakses oleh dokter yang bertugas di ruangan tertentu pada jam kerja.
Model ini lebih fleksibel dan mendukung fine-grained access control, sehingga cocok untuk aplikasi enterprise yang kompleks. Sisi lain, ABAC lebih sulit diimplementasikan dan dipelihara dibandingkan RBAC karena aturannya lebih banyak dan dinamis.
ReBAC (Relationship-Based Access Control)
ReBAC memberikan akses berdasarkan hubungan antara subjek dan resource, seperti pemilik, anggota tim, atau teman. Contohnya, di Google Drive, pemilik file dan orang yang diberi akses oleh pemilik dapat mengedit dokumen tersebut.
Model ini cocok untuk aplikasi kolaborasi dan jaringan sosial, di mana akses bergantung pada relasi antar entitas, bukan hanya pada role atau atribut statis.
DAC (Discretionary Access Control)
Dalam DAC, pemilik resource menentukan siapa yang boleh mengakses resource miliknya. Sistem file UNIX dengan perintah chmod adalah contoh klasik DAC. Model ini fleksibel bagi pemilik, tetapi rentan jika pemilik memberikan akses secara sembarangan tanpa pemahaman tentang risiko keamanan.
MAC (Mandatory Access Control)
MAC adalah model paling ketat. Akses ditentukan oleh kebijakan sentral yang biasanya dikelola oleh tim keamanan, bukan oleh pemilik resource. Label sensitivitas digunakan untuk mengelompokkan data dan pengguna. Model ini umumnya digunakan di lingkungan militer atau pemerintahan yang membutuhkan kontrol sangat ketat.
Untuk aplikasi web biasa, RBAC seringkali sudah cukup. Jika kamu membutuhkan kontrol yang lebih halus berdasarkan konteks, ABAC bisa dipertimbangkan. Sementara ReBAC adalah pilihan yang baik jika aplikasi kamu berfokus pada kolaborasi dan hubungan antar pengguna.
Scope & Permission Checking
Sebelum masuk ke implementasi di Laravel, penting untuk memahami perbedaan antara scope, permission, dan role, serta mengapa pemeriksaan harus dilakukan di backend.
Scope adalah string yang membatasi izin token, biasanya dalam konteks OAuth 2.0. Contoh scope adalah read:articles atau write:orders. Scope dievaluasi oleh Resource Server atau API Gateway sebelum endpoint dieksekusi.
Permission adalah izin spesifik pada suatu tindakan, misalnya post.create, post.delete, atau user.manage. Role adalah kumpulan permission. Sebuah role admin mungkin memiliki semua permission, sedangkan role editor hanya memiliki post.create dan post.edit.
Yang paling penting adalah: pemeriksaan otorisasi harus selalu dilakukan di backend. Frontend hanya untuk pengalaman pengguna, misalnya menyembunyikan tombol "Hapus" jika pengguna bukan admin. Namun, menyembunyikan tombol di frontend tidak mencegah seseorang untuk langsung memanggil endpoint backend. Backend adalah otoritas keamanan yang akhir menentukan apakah request diizinkan atau ditolak.
Laravel Authorization (Gate, Policy, Middleware)
Laravel menyediakan beberapa alat untuk mengimplementasikan Authorization: Gate, Policy, dan middleware otorisasi. Ketiga alat ini saling melengkapi dan dapat digunakan sesuai kebutuhan aplikasi kamu. Contoh kode di bagian ini ditargetkan untuk Laravel 10/11 dan PHP 8.2+.
Laravel Gate
Gate adalah closure sederhana untuk memeriksa apakah pengguna diizinkan melakukan suatu tindakan. Gate biasanya didefinisikan di AuthServiceProvider menggunakan metode Gate::define. Berikut adalah contoh:
use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
Gate::define('update-post', function (User $user, Post $post) {
return $user->id === $post->user_id;
});
Untuk memeriksa apakah pengguna diizinkan, kamu dapat menggunakan Gate::allows atau Gate::denies:
if (Gate::allows('update-post', $post)) {
// Pengguna diizinkan memperbarui postingan
}
if (Gate::denies('update-post', $post)) {
abort(403, 'Kamu tidak diizinkan mengedit postingan ini.');
}
Gate cocok untuk pemeriksaan otorisasi yang tidak terikat pada satu model tertentu, atau untuk tindakan yang melibatkan beberapa model sekaligus.
Laravel Policy
Policy adalah class yang terorganisir di sekitar model tertentu. Misalnya, PostPolicy untuk model Post dengan metode seperti view, create, update, delete, restore, dan forceDelete. Policy harus terdaftar di AuthServiceProvider melalui properti $policies.
Berikut adalah contoh lengkap PostPolicy:
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
public function view(User $user, Post $post): bool
{
return true; // Semua pengguna yang login boleh melihat postingan publik
}
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id || $user->role === 'admin';
}
public function delete(User $user, Post $post): bool
{
return $user->role === 'admin';
}
}
Dalam contoh ini, semua pengguna yang login dapat melihat postingan. Hanya pemilik postingan atau admin yang dapat memperbaruinya. Sedangkan hanya admin yang boleh menghapus postingan.
Contoh di atas menggunakan $user->role === 'admin' untuk mendeteksi administrator, yang asumsinya ada kolom role pada tabel users. Perhatikan bahwa hasRole bukan metode bawaan Laravel; metode tersebut berasal dari paket seperti spatie/laravel-permission atau harus didefinisikan sendiri pada model User. Jika kamu menggunakan pendekatan kolom role, pastikan kolom tersebut sudah ada dan diisi dengan benar.
Agar Policy di atas benar-benar berlaku, kamu harus mendaftarkannya di AuthServiceProvider melalui properti $policies. Gate juga biasanya didefinisikan di metode boot() pada class yang sama. Tanpa pendaftaran ini, Policy dan Gate akan diabaikan oleh Laravel. Berikut contoh lengkapnya:
namespace App\Providers;
use App\Models\Post;
use App\Models\User;
use App\Policies\PostPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Post::class => PostPolicy::class,
];
public function boot(): void
{
$this->registerPolicies();
Gate::define('update-post', function (User $user, Post $post) {
return $user->id === $post->user_id;
});
}
}
Untuk memeriksa policy, kamu dapat menggunakan $user->can('update', $post) di controller, helper can(), atau direktif Blade @can:
@can('update', $post)
<a href="/posts/{{ $post->id }}/edit">Edit</a>
@endcan
Jika otorisasi gagal, Laravel otomatis mengembalikan 403 Forbidden melalui AuthorizationException.
Middleware Otorisasi
Laravel menyediakan middleware can, canany, dan cannot untuk melindungi route. Middleware ini berguna ketika kamu ingin memeriksa otorisasi sebelum request mencapai controller.
Berikut adalah contoh route yang dilindungi oleh middleware otorisasi:
use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::put('/posts/{post}', [PostController::class, 'update'])
->middleware('auth', 'can:update,post');
Route::delete('/users/{user}', [UserController::class, 'destroy'])
->middleware('auth', 'can:delete,user');
Middleware can:update,post akan secara otomatis mencari model Post berdasarkan ID di URL dan memanggil metode update di policy terkait. Jika pengguna tidak diizinkan, Laravel akan mengembalikan 403 Forbidden.
Middleware canany memungkinkan kamu memeriksa beberapa kemampuan sekaligus, dan cukup satu di antaranya yang diizinkan untuk melewati middleware. Sedangkan cannot merupakan kebalikan dari can.
Scope Checking di API
Jika kamu membangun API dengan Laravel Sanctum atau Passport, verifikasi scope token juga merupakan bagian dari otorisasi. Sebelum mengeksekusi endpoint, pastikan token yang digunakan memiliki scope yang diperlukan. Misalnya, token dengan scope write:orders hanya boleh mengakses endpoint yang terkait dengan pembuatan atau pembaruan pesan.
Laravel Sanctum memungkinkan kamu membatasi token dengan scope tertentu saat membuat token. Di sisi server, kamu dapat memverifikasi scope sebelum memproses request agar aplikasi tidak secara tidak sengaja mengekspos fungsi yang seharusnya terbatas.
Ancaman Keamanan Umum pada Authorization
Tanpa otorisasi yang baik, aplikasi kamu rentan terhadap berbagai ancaman keamanan. OWASP mencantumkan Broken Access Control sebagai risiko teratas dalam Top 10. Berikut adalah ancaman umum yang harus kamu ketahui.
IDOR / BOLA (Broken Object Level Authorization)
IDOR, juga dikenal sebagai Broken Object Level Authorization (BOLA), terjadi ketika aplikasi memverifikasi identitas pengguna tetapi gagal memeriksa apakah pengguna berhak mengakses resource dengan ID tertentu. Contohnya, endpoint GET /api/invoices/999 mengembalikan invoice milik pelanggan lain hanya karena ID diganti di URL.
Dampaknya serius: penyerang dapat mencuri data massal dengan mencoba berbagai ID. Mitigasi utamanya adalah memvalidasi kepemilikan resource di backend. Setiap request yang mengakses resource harus memverifikasi apakah user_id pemilik resource sama dengan pengguna yang login.
Privilege Escalation
Privilege escalation terjadi ketika pengguna naik tingkat hak aksesnya untuk melakukan tindakan yang seharusnya tidak diizinkan. Ada dua jenisnya: horizontal (mengakses data milik pengguna lain dengan level yang sama) dan vertikal (pengguna biasa mengakses fungsi admin).
Mitunasinya dengan menerapkan RBAC atau ABAC yang ketat, serta memverifikasi role dan permission di backend. Jangan andalkan frontend untuk menyembunyikan fitur admin, karena penyerang dapat langsung memanggil endpoint admin tanpa melalui antarmuka pengguna.
Missing Access Control
Missing access control terjadi ketika endpoint atau resource tidak memiliki pemeriksaan otorisasi sama sekali. Akibatnya, endpoint dapat diakses oleh siapa saja, termasuk pengguna yang tidak login atau role yang salah.
Solusinya adalah menerapkan kebijakan deny-by-default. Pastikan setiap endpoint dilindungi oleh autentikasi dan otorisasi. Jangan biarkan endpoint terbuka kecuali sengaja dirancang untuk diakses publik.
Broken Function Level Authorization
Kerentanan ini terjadi ketika fungsi atau API yang dibatasi bagi role tertentu dapat diakses oleh pengguna non-admin karena pemeriksaan otorisasi pada tingkat fungsi hilang atau salah konfigurasi. Misalnya, endpoint /admin/delete-user dapat diakses oleh pengguna biasa.
Mitunasinya dengan menerapkan otorisasi pada tingkat fungsi atau endpoint menggunakan middleware can, serta memverifikasi role dan permission di controller.
Insecure Direct Object Reference
Insecure Direct Object Reference adalah ketika referensi objek langsung, seperti ID database, diekspos dalam URL tanpa otorisasi. Penyerang dapat menebak atau mengganti ID untuk mengakses objek milik orang lain.
Untuk mengurangi risiko ini, kamu dapat menggunakan ID acak atau UUID alih-alih ID berurutan, tetapi ini bukan pengganti untuk validasi kepemilikan resource. Selalu periksa apakah pengguna yang login berhak mengakses resource yang diminta.
Best Practices Authorization
Berikut adalah beberapa praktik terbaik yang dapat kamu terapkan untuk mengamankan otorisasi di aplikasi PHP dan Laravel.
Prinsip Least Privilege
Berikan pengguna hanya izin minimum yang dibutuhkan untuk menyelesaikan tugasnya. Hindari memberikan role admin kepada semua pengguna. Semakin sedikit izin yang dimiliki pengguna, semakin kecil dampak jika akun tersebut dicuri atau disalahgunakan.
Deny-by-Default
Secara default, tolak semua akses. Izinkan secara eksplisit hanya aturan yang telah disetujui. Jangan menggunakan pendekatan default-allow, di mana semua endpoint dapat diakses kecuali secara eksplisit dibatasi. Pendekatan deny-by-default jauh lebih aman.
Validasi di Backend
Selalu lakukan otorisasi di sisi server. Frontend hanya untuk pengalaman pengguna, bukan untuk keamanan. Bahkan jika tombol admin disembunyikan di Blade atau React, pengguna yang berpengalaman masih dapat mengakses endpoint admin secara langsung jika backend tidak memeriksa hak akses.
Validasi Kepemilikan Resource
Pada setiap request yang mengakses resource, verifikasi apakah user_id pemilik resource sama dengan pengguna yang login. Ini adalah cara terbaik untuk mencegah IDOR. Di Laravel, kamu dapat melakukannya di controller atau melalui Policy.
Contoh pemeriksaan kepemilikan di controller:
public function show(Invoice $invoice)
{
if ($invoice->user_id !== auth()->id()) {
abort(403, 'Kamu tidak diizinkan mengakses invoice ini.');
}
return $invoice;
}
Kode di atas memastikan bahwa pengguna hanya dapat mengakses invoice yang miliknya sendiri. Jika user_id tidak cocok, sistem mengembalikan 403 Forbidden.
Token Scope Terbatas
Untuk API, batasi scope token sesuai kebutuhan menggunakan OAuth 2.0 scopes. Verifikasi scope di Resource Server sebelum mengeksekusi endpoint. Jangan memberikan token dengan akses penuh jika aplikasi hanya membutuhkan izin terbatas.
Audit Log
Catat keputusan otorisasi penting, seperti siapa yang mengakses apa, kapan, serta hasilnya (diizinkan atau ditolak). Audit log berguna untuk deteksi intrusi dan keperluan forensik saat terjadi insiden keamanan.
Skenario Praktis untuk PHP & Laravel
Berikut adalah beberapa skenario umum dan rekomendasi implementasinya.
Blog atau CMS: Admin, Editor, dan Pembaca
Untuk blog atau CMS dengan tiga level pengguna, RBAC dengan Laravel Policy adalah pilihan yang tepat. Buat role admin, editor, dan viewer. Admin dapat membuat, mengedit, dan menghapus artikel. Editor hanya boleh mengedit. Viewer hanya boleh membaca. Implementasikan pemeriksaan ini di PostPolicy dan gunakan middleware can pada route yang terkait.
Aplikasi Kolaborasi File
Jika aplikasi kamu mirip Google Drive, di mana akses bergantung pada hubungan antara pengguna dan file, pertimbangkan ReBAC. Pemilik file dan anggota tim yang diberi akses dapat mengedit dokumen. Model ini lebih cocok daripada RBAC untuk skenario kolaborasi.
API REST untuk Mobile atau SPA
Untuk API yang digunakan oleh aplikasi mobile atau SPA, gunakan Laravel Sanctum atau Passport untuk autentikasi, serta verifikasi scope token untuk otorisasi. Pastikan setiap endpoint API memeriksa scope yang sesuai sebelum menyediakan data.
Halaman Admin Terbatas
Lindungi route admin dengan middleware can atau canany. Misalnya, route untuk mengelola pengguna hanya boleh diakses oleh pengguna dengan permission manage-users. Jangan lupa memasang middleware pada seluruh route admin, tidak hanya beberapa endpoints saja.
Mencegah IDOR pada Invoice
Pada endpoint GET /api/invoices/{id}, selalu validasi kepemilikan resource menggunakan where('user_id', auth()->id())->findOrFail($id) atau melalui Policy. Jangan langsung mencari invoice berdasarkan ID tanpa memeriksa pemiliknya.
Dokumen dengan Klasifikasi Sensitif
Jika aplikasi kamu menangani dokumen dengan klasifikasi sensitif, seperti data medis atau keuangan, ABAC dapat digunakan untuk mengevaluasi atribut subjek, resource, tindakan, dan lingkungan sebelum memberikan akses.
Masalah Umum & Pitfalls
Berikut adalah beberapa kesalahan yang sering terjadi saat mengimplementasikan otorisasi:
Pertama, mengandalkan otorisasi di frontend saja. Menyembunyikan tombol di Blade atau React tidak mencegah akses langsung ke endpoint backend.
Kedua, lupa memvalidasi kepemilikan resource. Endpoint mengembalikan data berdasarkan ID URL tanpa memeriksa apakah data milik pengguna yang login, yang mengakibatkan IDOR.
Ketiga, pendekatan default-allow. Semua endpoint dapat diakses kecuali secara eksplisit dibatasi. Ini seharusnya sebaliknya dengan deny-by-default.
Keempat, role yang terlalu lebar. Memberi role admin kepada pengguna yang hanya butuh izin terbatas meningkatkan risiko keamanan.
Kelima, token scope tidak diverifikasi. API menerima token tanpa memeriksa apakah token memiliki scope yang diperlukan.
Keenam, mengandalkan input klien untuk keputusan otorisasi. Menyembunyikan role atau permission di JWT claim tanpa verifikasi signature dan source of truth di backend berbahaya.
Ketujuh, middleware otorisasi tidak dipasang pada seluruh route admin. Beberapa endpoint admin lupa dilindungi, sehingga dapat diakses oleh pengguna non-admin.
Penutup
Authorization (otorisasi) adalah proses menentukan apakah identitas yang telah diverifikasi diizinkan melakukan tindakan tertentu pada sumber daya. Ia bekerja setelah Authentication dan menjawab pertanyaan "Apa yang boleh kamu lakukan?", berbeda dengan Authentication yang menjawab "Siapa kamu?".
Pemilihan model otorisasi harus disesuaikan dengan kebutuhan aplikasi. RBAC cocok untuk aplikasi sederhana dengan role yang jelas, ABAC untuk kontrol fine-grained yang kompleks, dan ReBAC untuk aplikasi kolaborasi yang bergantung pada hubungan antar pengguna. Di Laravel, kamu dapat mengimplementasikan otorisasi menggunakan Gate, Policy, dan middleware can, serta memverifikasi scope token untuk API.
Terapkan best practice seperti prinsip least privilege, deny-by-default, validasi di backend, dan validasi kepemilikan resource untuk mencegah ancaman seperti IDOR dan privilege escalation. Jangan pernah mengandalkan frontend untuk keamanan, karena backend adalah otoritas terakhir dalam menentukan apakah request diizinkan atau ditolak.
Jika kamu ingin mengevaluasi keamanan aplikasi yang sudah ada, mulai dengan audit implementasi otorisasi: periksa Gate dan Policy yang telah didefinisikan, pastikan middleware route terpasang dengan benar, validasi kepemilikan resource di controller, dan verifikasi scope token di API.
Referensi terkait: OWASP Authorization Cheat Sheet, Laravel Authorization Documentation.
Jika kamu ingin mendalami topik keamanan dan otorisasi terkait, baca artikel tentang Authentication dan Cara Kerjanya dan Perbedaan Authentication dan Authorization.
Fitur komentar belum diaktifkan oleh administrator.