Memahami RBAC di Aplikasi Dashboard
Role-Based Access Control (RBAC) menyederhanakan pengelolaan otorisasi dengan memetakan pengguna ke role, dan role ke permission. Dalam konteks dashboard atau panel admin, RBAC membantu memastikan fitur kritis hanya bisa digunakan oleh role yang tepat, seperti admin super, manajer produk, atau auditor.
Desain RBAC yang baik mempertimbangkan sisi frontend & backend. Di sisi frontend, RBAC mendukung pengalaman pengguna yang bersih dan responsif dengan menyembunyikan tombol yang tidak perlu, sementara backend tetap menjadi garis pertahanan terakhir agar tidak ada pengguna yang bisa memanggil API berhak lebih tinggi hanya dengan memanipulasi JavaScript.
Pada aplikasi Nuxt 3, pendekatan RBAC yang maintainable mencakup: (1) mendefinisikan role permintaan, (2) menyimpan state user dan permission secara efisien, (3) middleware route protection, dan (4) validasi ulang di backend.
Desain Role dan Permission
Langkah pertama adalah mendesain struktur role dan permission yang dapat berevolusi. Untuk medium-scale dashboard, gunakan pemisahan jelas antara role (siapa) dan permission (apa). Contoh sederhana:
const rolePermissions = {
superAdmin: ['manage_users', 'view_reports', 'modify_settings'],
productManager: ['view_catalog', 'edit_catalog', 'view_reports'],
inventoryViewer: ['view_stock', 'view_reports'],
};
const permissionToComponents = {
view_reports: ['ReportPage', 'FinancialChart'],
edit_catalog: ['ProductForm'],
};
Mapping semacam ini bisa disimpan dalam modul konfigurasi atau bahkan file JSON yang bisa di-load secara dinamis. Kunci utamanya adalah menjaga determinisme: role tertentu selalu memiliki daftar permission yang bisa diuji secara programatik.
Agar mudah dipelihara, pisahkan permission internal (misal, permission untuk feature toggle) dari permission yang diserialisasi ke frontend. Dalam Nuxt 3, cukup kirimkan daftar permission yang dibutuhkan UI dibanding sepasang role + permission berlebih.
Penyimpanan State User dan Permission
Gunakan Pinia sebagai store global untuk menyimpan profile user dan permission setelah login. Ini memberikan akses aman ke role di seluruh komponen dan middleware.
// stores/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
profile: null as null | { id: number; name: string; role: string; permissions: string[] },
token: '',
}),
getters: {
can(): (permission: string) => boolean {
return (permission) => this.profile?.permissions.includes(permission) ?? false;
},
},
actions: {
setUser(payload: { profile: { id: number; name: string; role: string; permissions: string[] }; token: string }) {
this.profile = payload.profile;
this.token = payload.token;
},
clearUser() {
this.profile = null;
this.token = '';
},
},
});
Store ini juga bisa memuat getter untuk memeriksa permission tertentu. Setelah login, data ini digunakan oleh komponen dan middleware untuk menentukan tampilan dan akses.
Proteksi Route dengan Middleware Nuxt 3
Nuxt 3 mendukung route middleware yang bisa dijalankan sebelum halaman dimuat. Untuk RBAC, buat middleware yang memeriksa permission yang terikat ke setiap halaman:
// middleware/check-permission.global.ts
import { defineNuxtRouteMiddleware, navigateTo } from '#app';
import { useUserStore } from '~/stores/user';
export default defineNuxtRouteMiddleware((to) => {
const userStore = useUserStore();
if (!userStore.profile) {
return navigateTo('/login');
}
const requiredPermission = to.meta.permission as string | undefined;
if (requiredPermission && !userStore.can(requiredPermission)) {
return navigateTo('/401');
}
});
Setiap route dapat menyertakan meta.permission:
export default defineNuxtRouteMiddleware((to) => {
const userStore = useUserStore();
});
export default definePageMeta({
middleware: ['check-permission'],
permission: 'manage_users',
});
Penting memastikan middleware dijalankan secara global atau minimal di grup halaman dashboard. Middleware memeriksa login state terlebih dahulu, kemudian permission. Jika permission tidak cukup, redirect ke halaman 401 atau custom error page.
Kontrol Akses Komponen di UI
Selain route, UI juga perlu menyembunyikan elemen seperti tombol dan form berdasarkan permission. Misalnya tombol “Hapus Produk” hanya boleh muncul bagi role tertentu.
HapusUntuk komponen yang lebih kompleks, pertimbangkan membuat composable helper seperti usePermission yang menghimpun logic permission, sehingga komponen tetap sederhana.
Pastikan juga bagian UI yang tersembunyi tetap tidak di-render di DOM jika pengguna tidak berhak, agar tidak bisa diaktifkan melalui DevTools.
Alur Login dan Redirect Saat Akses Ditolak
Alur login standar untuk dashboard Nuxt 3 bisa berupa:
- Pengguna memasukkan kredensial.
- Frontend memanggil endpoint login backend.
- Backend mengembalikan token (JWT/Opaque) dan profil beserta permission yang valid.
- Frontend menyimpan token di
piniadan/atauuseStateSSR, lalu redirect ke halaman dashboard.
Contoh panggilan API:
const login = async (credentials: { email: string; password: string }) => {
const response = await $fetch('/api/auth/login', {
method: 'POST',
body: credentials,
});
const userStore = useUserStore();
userStore.setUser({ profile: response.profile, token: response.token });
};
Jika pengguna mencoba mengakses route atau fitur tanpa permission, middleware harus menolak dan redirect ke halaman khusus. Gunakan navigateTo agar browser tidak menampilkan halaman yang dibatasi.
Untuk page-level guard, set meta route berikut:
definePageMeta({
middleware: ['check-permission'],
permission: 'view_reports',
});
Halaman 401/403 bisa menampilkan detail scope permission yang dibutuhkan beserta tautan ke halaman bantuan.
Validasi Ulang di Backend
Frontend tidak boleh menjadi satu-satunya antarmuka RBAC. Seluruh permintaan API harus memeriksa token dan permission dari sisi server. Sebagai contoh, di backend Express/Node:
app.post('/api/products', authenticate, authorize('edit_catalog'), async (req, res) => {
// Logika tambah produk
});
Middleware authorize memeriksa apakah token memiliki permission yang dibutuhkan. Validasi ini penting karena pengguna bisa memanggil API langsung menggunakan tools seperti Postman.
Usahakan backend menyimpan mapping role-permission yang sama seperti frontend agar konsistensi tetap terjaga. Jika perlu, buat shared configuration (misalnya dalam file JSON) yang digunakan untuk mengeneralisasi validasi baik di backend maupun frontend.
Pola Maintainable untuk Aplikasi Skala Menengah
Untuk scale menengah, sejumlah pola membantu menjaga RBAC tetap manageable:
- Centralized Permission Registry: Simpan permission dan role di satu tempat (misalnya
/config/permissions.ts) agar semua pihak memakai standar sama. - Composable Helpers: Buat composable seperti
useAccessuntuk memo permission, sehingga komponen bisa memanggilconst { can, cannot } = useAccess();. - Testing: Uji middleware dan backend authorization agar tidak ada permission leak. Coba skenario pengguna dengan role berbeda dan pastikan akses hanya aktif ketika diizinkan.
- Audit: Catat siapa melakukan perubahan permission (misal admin revoke) untuk kebutuhan compliance.
Adapun trade-off yang perlu diperhatikan: semakin granular permission, semakin kompleks mapping dan maintenance. Pastikan hanya menambahkan permission baru jika benar-benar dibutuhkan. Juga, pinia store yang memuat permission harus sinkron dengan data backend; gunakan refresh token atau polling untuk memastikan permission terbaru dipakai.
Debugging dan Tips
Beberapa hal yang sering jadi jebakan:
- Permission tidak disinkron: Pastikan response login menyertakan permission yang dipakai frontend. Gunakan log di backend untuk memastikan permission benar.
- Middleware tidak terdaftar: Nuxt membutuhkan file middleware disimpan di folder
middlewaredan nama file sesuai dipanggil. GunakandefineNuxtRouteMiddlewareagar dukungan Nuxt 3 penuh. - Token hilang pada refresh: Jika SSR, simpan token di
useStateatau cookie yang aman agar middleware tidak kehilangan state saat refresh.
Untuk melihat status RBAC saat runtime, buat panel _debug_ domain tertentu yang hanya bisa diakses super admin. Tampilkan role dan permission saat ini agar mudah audit dan troubleshooting.
Implementasi RBAC yang solid di Nuxt 3 tidak hanya meningkatkan keamanan tetapi juga membantu tim menjaga UI tetap relevan dengan hak akses pengguna. Dengan middleware yang tepat, penyimpanan state terstruktur, dan proteksi backend, dashboard Anda akan lebih mudah dipelihara sekaligus aman.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!