BAB 30. AUTHENTICATION FLOW
Arsitektur Autentikasi
flowchart LR
A["📱 Flutter App"] -->|"POST /auth/login"| B["🔐 Laravel Sanctum"]
B -->|"Verify"| C[("💾 MySQL")]
C -->|"User Data"| B
B -->|"Personal Access Token"| A
A -->|"Store"| D["🔒 Flutter\nSecure Storage"]
A -->|"Bearer Token"| E["🌐 All API Endpoints"]
E -->|"auth:sanctum middleware"| B
Authentication Flow Detail
flowchart TD
A["📱 Flutter: Buka App"] --> B{{"Token ada\ndi Secure Storage?"}}
B -->|Tidak| C["🔑 Tampilkan Login Screen"]
B -->|Ya| D["✅ Cek Token Valid"]
D --> E{{"Token Masih Valid?"}}
E -->|Tidak| C
E -->|Ya| F["🏠 Dashboard"]
C --> G["✏️ Input Username & Password"]
G --> H["📤 POST /api/v1/auth/login"]
H --> I{{"Response?"}}
I -->|401 Error| J["❌ Tampilkan Error"]
J --> G
I -->|200 OK| K["💾 Simpan Token ke\nSecure Storage"]
K --> L{{"must_change_password?"}}
L -->|true| M["🔄 Paksa Ganti Password"]
M --> N["📤 POST /auth/change-password"]
N --> F
L -->|false| F
Token Management
| Komponen | Mekanisme | Detail |
|---|---|---|
| Access Token | Laravel Sanctum Personal Access Token | Dibuat saat login berhasil |
| Storage | Flutter Secure Storage | Terenkripsi di device |
| Pengiriman | HTTP Header Authorization: Bearer {token} | Setiap request ke API |
| Logout | Revoke token di server | Token dihapus dari DB |
| Expired | Token tidak punya TTL default | User harus logout manual |
| Multi-device | Setiap login = token baru | Bisa revoke per device |
Middleware yang Digunakan
| Middleware | Fungsi |
|---|---|
auth:sanctum | Wajib login untuk mengakses endpoint |
role:student | Hanya siswa yang boleh akses |
role:teacher | Hanya guru yang boleh akses |
role:admin | Hanya admin sekolah yang boleh akses |
role:super_admin | Hanya super admin yang boleh akses |
verified.school | Memastikan sekolah pengguna aktif |
active.academic.year | Memastikan tahun ajaran aktif |
Contoh penggunaan di Laravel Route:
// routes/api.php
Route::prefix('v1')->group(function () {
// Public routes
Route::post('/auth/login', [AuthController::class, 'login']);
// Protected routes
Route::middleware('auth:sanctum')->group(function () {
Route::post('/auth/logout', [AuthController::class, 'logout']);
Route::post('/auth/change-password', [AuthController::class, 'changePassword']);
// Student only
Route::middleware('role:student')->group(function () {
Route::apiResource('requests', RequestController::class);
Route::post('ratings', [RatingController::class, 'store']);
});
// Teacher only
Route::middleware('role:teacher')->group(function () {
Route::get('dashboard/teacher', [DashboardController::class, 'teacher']);
});
// Admin only
Route::middleware('role:admin')->group(function () {
Route::get('dashboard/admin', [DashboardController::class, 'admin']);
});
});
});
Keamanan Autentikasi
| Fitur | Implementasi | Detail |
|---|---|---|
| Password Hash | Bcrypt / Argon2id | Default Laravel Hash::make() |
| HTTPS | Wajib di production | TLS 1.2 minimum |
| Rate Limiting | Laravel RateLimiter | 5x percobaan login per menit per IP |
| Login History | Tabel login_histories | IP, device, timestamp |
| Device Tracking | User-Agent + IP | Disimpan bersama token |
| Token Revocation | $user->tokens()->delete() | Logout dari semua device |
| Audit Log | Event listener | Setiap aksi kritis tercatat |
Security Headers (Laravel Response)
// app/Http/Middleware/SecurityHeaders.php
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'DENY');
$response->headers->set('X-XSS-Protection', '1; mode=block');
$response->headers->set('Strict-Transport-Security', 'max-age=31536000');
:::note Catatan Implementasi Dokumen BAB 21–30 ini menjadi fondasi implementasi backend Laravel 12, struktur database MySQL, endpoint REST API, autentikasi Laravel Sanctum, serta integrasi Flutter melalui Riverpod dan Clean Architecture pada bab berikutnya. :::