From 6c6a34db9fcb6775cc858f70bab5af5409b2eb21 Mon Sep 17 00:00:00 2001 From: Corentin JOGUET Date: Fri, 19 Jun 2026 16:15:41 +0200 Subject: [PATCH] fix(borne): passerelle /api same-origin sur le vhost kiosk (#62) --- docker/apache/vhost.conf | 25 +++++++++++++++++++++++++ docs/api/conventions.md | 11 ++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/docker/apache/vhost.conf b/docker/apache/vhost.conf index 141483e..05e18f6 100644 --- a/docker/apache/vhost.conf +++ b/docker/apache/vhost.conf @@ -55,7 +55,10 @@ # SPA-like fallback : toute URL non-fichier -> index.html # (pour permettre de bookmarker un chemin profond dans la borne). + # Exclusion /api/ : ces requetes sont relayees a l'API (cf. + # plus bas) et ne doivent JAMAIS retomber sur index.html. RewriteEngine On + RewriteCond %{REQUEST_URI} !^/api/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.html [L] @@ -66,6 +69,28 @@ Require all denied + # === API en MEME origine (P4 - passerelle same-origin) === + # La borne consomme l'API publique (/api/*) sur SA PROPRE origine : ce vhost + # relaie ces requetes au front controller admin via PHP-FPM. data.js garde + # donc ses URLs relatives (/api/categories...) -> aucune requete cross-origin + # cote borne -> CORS inutile pour ce parcours (le middleware reste en place + # cote API comme defense en profondeur). SEUL /api est relaye : le back-office + # (/login, /admin/*) n'est PAS joignable depuis l'origine borne. + # + # Le chemin apres host:port dans l'URL fcgi EST le SCRIPT_FILENAME envoye a + # FPM : on le force sur le front controller admin (un .php REEL). Sans ca, FPM + # recevrait un chemin sous le docroot borne sans extension .php et rejetterait + # (security.limit_extensions par defaut = .php -> reponse "Access denied"). + # ProxyPassMatch intercepte des la phase translate -> le faux chemin + # /.../borne/api/... n'est jamais calcule. REQUEST_URI (=/api/categories) et la + # query string sont preserves -> le Router (qui lit REQUEST_URI) route correctement. + ProxyPassMatch "^/api(/.*)?$" "fcgi://wakdo-app:9000/var/www/html/public/admin/index.php" + # mod_proxy_fcgi derive un SCRIPT_FILENAME corrompu (prefixe proxy: + chemin + # original colle apres index.php) -> FPM rejette (extension != .php). On force + # la valeur sur le front controller admin (un .php REEL) ; REQUEST_URI reste + # intact, donc le Router route correctement. + ProxyFCGISetEnvIf "true" SCRIPT_FILENAME "/var/www/html/public/admin/index.php" + # Compression text/html, css, js, json (Cr 1.e.8 temps de chargement). AddOutputFilterByType DEFLATE text/html text/css text/javascript \ diff --git a/docs/api/conventions.md b/docs/api/conventions.md index 395012d..e7c1210 100644 --- a/docs/api/conventions.md +++ b/docs/api/conventions.md @@ -307,9 +307,14 @@ ici. ## 10. CORS -L'API admin sous `/api/*` autorise l'origine du kiosk via `CORS_ALLOWED_ORIGIN` (valeur exacte, -sans joker), configuree dans `docker/apache/vhost.conf`. L'origine doit correspondre a -`APP_URL_KIOSK`. +La borne consomme `/api/*` en **meme origine** : le vhost kiosk (`docker/apache/vhost.conf`) +relaie `/api/*` au front controller admin via PHP-FPM (`ProxyPassMatch` + `ProxyFCGISetEnvIf` +qui force `SCRIPT_FILENAME` sur `public/admin/index.php`). `data.js` garde donc des URLs +relatives et le navigateur n'emet pas de requete cross-origin pour ce parcours. + +Le middleware `App\Core\Cors` reste en place comme defense en profondeur : il lit +`CORS_ALLOWED_ORIGIN` (valeur exacte, sans joker, = `APP_URL_KIOSK`) et autorise un eventuel +consommateur cross-origin de l'API. Il n'est pas sur le chemin de la borne. ---