Files
musadaq-saas/app/Middleware/CsrfMiddleware.php

44 lines
1.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Middleware;
use App\Core\{Request, Response};
final class CsrfMiddleware
{
public function handle(Request $request, callable $next): mixed
{
// Skip CSRF check for safe methods
if (in_array($request->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);
}
}