getMethod(), ['GET', 'HEAD', 'OPTIONS'])) { return $next($request); } // For APIs, we often use a custom header or check origin // If we use sessions for tokens: if (session_status() === PHP_SESSION_NONE) { session_start(); } $token = $request->getHeader('X-CSRF-TOKEN') ?: ($request->getBody()['_csrf'] ?? null); $sessionToken = $_SESSION['csrf_token'] ?? null; if (!$token || !$sessionToken || !hash_equals($sessionToken, $token)) { // For now, if we are purely API with Bearer token, we might skip this. // But if the request has a session or cookie, it's mandatory. // If the Authorization header is present, we might assume it's an API call // that is naturally protected against CSRF if not using cookies for Auth. if ($request->getHeader('Authorization')) { return $next($request); } Response::error('رمز الحماية (CSRF) غير صالح أو مفقود', 'CSRF_INVALID', 403); return null; } return $next($request); } }