Lewati ke konten utama

BAB 42. MIDDLEWARE

Tujuan

Middleware digunakan untuk melakukan validasi, autentikasi, otorisasi, logging, dan pembatasan akses sebelum request mencapai controller.


Alur Middleware

flowchart LR
R["📥 Request"] --> H["🔒 Force HTTPS"]
H --> T["✂️ Trim Strings"]
T --> RL["⏱️ Rate Limiter"]
RL --> LOG["📝 Request Logging"]
LOG --> A["🔐 auth:sanctum"]
A --> RO["👤 Role Check"]
RO --> SC["🏫 School Context"]
SC --> AY["📅 Academic Year"]
AY --> C["🎛️ Controller"]

style A fill:#dc2626,color:#fff
style C fill:#059669,color:#fff

Middleware Global

Diterapkan ke semua request secara otomatis.

MiddlewareFungsi
ForceHttpsMemastikan semua request menggunakan HTTPS
TrimStringsMembersihkan whitespace di input
ConvertEmptyStringsMengubah string kosong menjadi null
RequestLoggingMencatat semua request untuk audit
ThrottleRequestsMembatasi jumlah request (rate limiter)

Middleware Autentikasi

// Wajib login — berlaku untuk semua protected route
Route::middleware('auth:sanctum')->group(function () {
// protected routes here
});

Middleware Role (RBAC)

Memastikan pengguna memiliki role yang tepat untuk mengakses endpoint.

MiddlewareRole yang Diizinkan
role:studentSiswa
role:teacherGuru
role:adminAdmin Sekolah
role:super_adminSuper Admin
// app/Http/Middleware/RoleMiddleware.php

public function handle(Request $request, Closure $next, string ...$roles): Response
{
if (!in_array($request->user()->role, $roles)) {
abort(403, 'Unauthorized action.');
}
return $next($request);
}

Middleware School Context

Memastikan pengguna hanya dapat mengakses data milik sekolahnya sendiri. Kritis untuk implementasi multi-tenant.

// app/Http/Middleware/VerifiedSchoolMiddleware.php

public function handle(Request $request, Closure $next): Response
{
$user = $request->user();

if (!$user->school || !$user->school->is_active) {
abort(403, 'Sekolah tidak aktif atau tidak ditemukan.');
}

// Inject school_id ke semua query secara otomatis via scope
app()->instance('current_school_id', $user->school_id);

return $next($request);
}

Middleware Academic Year

Memastikan tahun ajaran aktif tersedia sebelum aktivitas akademik dapat dilakukan.

// Otomatis menolak request jika tidak ada tahun ajaran aktif
// di sekolah pengguna yang sedang login

Middleware Stack per Route Group

// routes/api.php

Route::prefix('v1')->group(function () {

// Public
Route::post('/auth/login', [AuthController::class, 'login'])
->middleware('throttle:5,1'); // 5 req per menit

// Protected
Route::middleware([
'auth:sanctum',
'verified.school',
'active.academic.year',
])->group(function () {

// Student only
Route::middleware('role:student')->group(function () {
Route::apiResource('requests', RequestController::class);
});

// Teacher only
Route::middleware('role:teacher')->group(function () {
Route::get('dashboard/teacher', [DashboardController::class, 'teacher']);
});
});
});