Autentikasi & Otorisasi
Dokumentasi lengkap sistem autentikasi dan otorisasi di LMS Codeverta.
Ikhtisar Sistem Autentikasiβ
LMS Codeverta menggunakan JWT (JSON Web Token) berbasis autentikasi dengan dukungan Access Token dan Refresh Token. Sistem ini juga mendukung session-based authentication sebagai fallback, serta WebAuthn (Passkey) untuk autentikasi tanpa password.
Alur Autentikasi Dasarβ
ββββββββββββ ββββββββββββ ββββββββββββ
β Client β β API β β Database β
ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ
β β β
β POST /login β β
β {email, pass} β β
ββββββββββββββββββββΆβ β
β β Verify Creds β
β ββββββββββββββββββββΆβ
β βββββββββββββββββββββ
β β β
β {access_token β β
β refresh_token} β β
βββββββββββββββββββββ β
β β β
β GET /courses β β
β (Bearer token) β β
ββββββββββββββββββββΆβ β
β β Validate JWT β
β β (middleware) β
β β β
β {courses data} β β
βββββββββββββββββββββ β
Metode Autentikasiβ
1. Login dengan Email & Passwordβ
Metode autentikasi standar menggunakan email dan password.
Endpoint: POST /api/auth/login
Request:
{
"email": "user@example.com",
"password": "password123"
}
Response (Sukses):
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": "uuid-user",
"email": "user@example.com",
"display_name": "User Display Name",
"role": 1,
"status": 1
},
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
}
2. Refresh Tokenβ
Access Token memiliki masa berlaku yang pendek (5 menit). Gunakan Refresh Token untuk mendapatkan Access Token baru tanpa login ulang.
Endpoint: POST /api/auth/refresh
Request:
{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
Response:
{
"success": true,
"message": "Token refreshed successfully",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs... (new)",
"refresh_token": "eyJhbGciOiJIUzI1NiIs... (new)"
}
}
3. WebAuthn (Passkey)β
LMS Codeverta mendukung WebAuthn untuk autentikasi tanpa password menggunakan passkey (biometric, PIN, atau security key).
Cara Kerja:
- User melakukan registrasi perangkat (public key disimpan di server)
- Saat login, user cukup menggunakan sidik jari, face ID, atau PIN
- Tidak perlu memasukkan password
Endpoint WebAuthn:
POST /api/auth/webauthn/register/beginβ Memulai registrasi passkeyPOST /api/auth/webauthn/register/finishβ Menyelesaikan registrasiPOST /api/auth/webauthn/login/beginβ Memulai login passkeyPOST /api/auth/webauthn/login/finishβ Menyelesaikan login
4. Session-Based Authentication (Fallback)β
Selain JWT, sistem juga mendukung session-based auth menggunakan gin-contrib/sessions:
- Session disimpan di Redis (jika Redis enabled) atau Cookie store (fallback)
Token Lifetime & Securityβ
Access Tokenβ
| Properti | Nilai |
|---|---|
| Durasi | 5 menit |
| Penyimpanan | Memory / localStorage (client) |
| Penggunaan | Setiap request ke API (Authorization header) |
| Risiko | Informasi bisa dibaca payload (base64 encoded, bukan encrypted) |
Refresh Tokenβ
| Properti | Nilai |
|---|---|
| Durasi | 7 hari |
| Penyimpanan | httpOnly cookie / secure storage |
| Penggunaan | Hanya untuk mendapatkan access token baru |
| Keamanan | Harus disimpan dengan aman (jangan di localStorage) |
Best Practice Keamanan Tokenβ
- Simpan access token di memory β Jangan di localStorage (rawan XSS)
- Simpan refresh token di httpOnly cookie β Tidak bisa diakses JavaScript
- Gunakan HTTPS β Enkripsi semua komunikasi
- Rotasi refresh token β Setiap kali refresh, token lama tidak valid
- Set expiry yang wajar β Access token pendek, refresh token lebih panjang
- Jangan sertakan data sensitif di payload JWT β Payload hanya base64 encoded
Otorisasi: Role-Based Access Control (RBAC)β
Level Roleβ
LMS Codeverta menggunakan sistem RBAC dengan level numerik:
| Role | Level | Kode | Deskripsi |
|---|---|---|---|
| Super Admin | 100 | role_admin_root | Akses penuh ke semua fitur sistem |
| Admin | 99 | role_admin | Akses manajemen platform sehari-hari |
| Mentor | 30 | role_mentor | Mengelola siswa, menilai tugas |
| Orang Tua | 10 | role_parent | Memantau progres belajar anak |
| Siswa | 1 | role_common_user / role_student | Mengakses kursus dan belajar |
Pengecekan Role di Backendβ
Backend memeriksa role user di setiap endpoint yang memerlukan otorisasi:
// Contoh pengecekan role di controller
userID, role, ok := currentLMSUser(c)
if role < 99 {
sendError(c, http.StatusForbidden, "Insufficient permission", nil)
return
}
Route Protectionβ
Setiap route group dilindungi oleh middleware yang sesuai:
| Route Group | Minimum Role | Middleware |
|---|---|---|
/api/auth/* | Public | - |
/api/me/* | 1 (Siswa) | Auth middleware |
/api/students/* | 1 (Siswa) | Auth middleware |
/api/admin/* | 99 (Admin) | Auth + Admin middleware |
/api/lms/admin/* | 99 (Admin) | Auth + Admin middleware |
/api/lms/mentor/* | 30 (Mentor) | Auth + Mentor middleware |
/api/lms/students/* | 1 (Siswa) | Auth middleware |
/api/parent/* | 10 (Orang Tua) | Auth + Parent middleware |
Hierarki Aksesβ
Super Admin (100) βββ Bisa melakukan apa saja
β
Admin (99) βββ Bisa mengelola semua kecuali Super Admin
β
Mentor (30) βββ Bisa mengelola siswa dan tugas
β
Orang Tua (10) βββ Bisa memantau anak sendiri
β
Siswa (1) βββ Bisa mengakses kursus dan belajar
Aturan Hierarki:
- User hanya bisa memodifikasi user dengan role lebih rendah
- Super Admin (100) tidak bisa dimodifikasi oleh siapapun
- User tidak bisa menaikkan role user lain ke level yang sama atau lebih tinggi
Middleware Autentikasiβ
Auth Middlewareβ
Auth middleware memverifikasi token JWT atau session sebelum mengizinkan akses ke endpoint:
// Pseudocode middleware auth
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := extractBearerToken(c)
if token == "" {
// Cek session sebagai fallback
session := sessions.Default(c)
userID := session.Get("id")
if userID == nil {
sendError(c, 401, "Unauthorized", nil)
c.Abort()
return
}
} else {
// Validasi JWT
claims, err := validateToken(token)
if err != nil {
sendError(c, 401, "Invalid token", nil)
c.Abort()
return
}
c.Set("id", claims.UserId)
c.Set("role", claims.Role)
}
c.Next()
}
}
Admin Middlewareβ
Memeriksa apakah user memiliki role admin (β₯ 99) setelah autentikasi.
Tenant Middlewareβ
TenantMiddleware digunakan untuk mendukung multi-tenant. Middleware ini:
- Mengekstrak identitas tenant dari subdomain atau header
- Menyimpan tenant context di request
- Data query akan di-scope berdasarkan tenant
Alur Login Lengkapβ
Flow Diagramβ
User membuka LMS Codeverta
β
βΌ
Halaman Login (Email/PW atau WebAuthn)
β
βΌ
User memasukkan kredensial
β
βΌ
βββββββββββββββββββββββββββββββββ
β Backend memverifikasi: β
β 1. Email terdaftar? β
β 2. Password cocok? β
β 3. Akun aktif? β
β 4. Password login enabled? β
βββββββββββββββββ¬ββββββββββββββββ
β
βββββββββββ΄βββββββββββ
βΌ βΌ
Success Failed
β β
βΌ βΌ
Generate Access Response error
Token + Refresh dengan pesan
Token & simpan yang sesuai
session
β
βΌ
Response ke client:
- User info (safe)
- Access token
- Refresh token
β
βΌ
Client redirect ke
Dashboard sesuai role
Kondisi Gagal Loginβ
| Kondisi | HTTP Status | Pesan |
|---|---|---|
| Email tidak terdaftar | 400 | "Invalid parameters" / "User not found" |
| Password salah | 400 | "Invalid parameters" |
| Akun dinonaktifkan | 403 | "Your account has been deactivated..." |
| Password login disabled | 400 | "Password login has been disabled..." |
Logoutβ
Endpoint: POST /api/auth/logout
Proses logout:
- Client menghapus access token dari memory
- Refresh token dihapus dari cookie/storage
- (Opsional) Backend bisa mem-blacklist token yang masih valid
Registrasi Pengguna Baruβ
Endpoint: POST /api/auth/register
Ketentuan Registrasiβ
- Registrasi harus diaktifkan oleh admin (
RegisterEnabled) - Registrasi password harus diaktifkan (
PasswordRegisterEnabled) - Jika email verification aktif, user harus memverifikasi email terlebih dahulu
Requestβ
{
"username": "newuser",
"email": "newuser@example.com",
"password": "password123",
"display_name": "New User",
"verification_code": "123456" // (jika email verification enabled)
}
Responseβ
{
"success": true,
"message": "Participant successful",
"data": {
"username": "newuser",
"display_name": "New User",
"email": "newuser@example.com"
}
}
Manajemen Tokenβ
Struktur JWT Payloadβ
{
"id": "uuid-user",
"username": "username",
"role": 1,
"iss": "gin-template",
"exp": 1700000000,
"iat": 1699999700
}
Verifikasi Token (di Backend)β
Backend memverifikasi token dengan:
- Memeriksa signature (HMAC-SHA256 dengan secret key)
- Memeriksa expiry (token kadaluarsa ditolak)
- Memeriksa issuer ("gin-template")
- Mengekstrak user ID dan role dari claims
FAQ Autentikasiβ
Apakah saya bisa login di beberapa perangkat sekaligus?β
Ya, Anda bisa login di beberapa perangkat. Setiap perangkat akan mendapatkan token yang berbeda.
Kenapa saya tiba-tiba logout?β
Access token memiliki masa berlaku 5 menit. Jika refresh token juga kedaluwarsa (7 hari), Anda harus login ulang.
Apakah password saya aman?β
Password disimpan dalam bentuk hash (bukan plain text) menggunakan algoritma hashing yang aman. Backend tidak pernah menyimpan password asli.
Bagaimana WebAuthn bekerja?β
WebAuthn menggunakan public key cryptography. Perangkat Anda membuat pasangan kunci (public & private). Kunci public disimpan di server, kunci private tetap aman di perangkat Anda. Saat login, server memverifikasi bahwa Anda memiliki kunci private tanpa perlu mengirimkannya.
Apakah session saya tetap ada setelah refresh token kedaluwarsa?β
Tidak. Setelah refresh token kedaluwarsa (7 hari), Anda perlu login ulang untuk mendapatkan token baru.
Terakhir diperbarui: Juni 2026