Cómo habla el panel con el backend
El panel de gestión es una aplicación aparte. No comparte proceso con el backend, no comparte base de datos y no importa su código: le habla por HTTP, como se lo hablaría cualquier otro programa.
Esta página explica por qué está montado así, que es lo que no se deduce leyendo el código.
El token no está en el navegador
Sección titulada «El token no está en el navegador»Es la decisión de la que cuelga todo lo demás.
Lo habitual en un panel de administración es guardar el token de sesión en
localStorage y mandarlo como Authorization: Bearer …. Funciona, es cómodo, y
tiene un problema que no se ve hasta que es tarde: cualquier ejecución de
JavaScript ajeno en el panel se lo lleva. Una dependencia comprometida, un
campo de texto que se pinta sin escapar, una extensión del navegador. Y con ese
token se entra desde cualquier sitio, sin contraseña y sin dejar un solo intento
fallido en el registro que alguien pueda mirar.
Aquí el token vive en el servidor del propio panel. El navegador solo tiene una cookie:
HttpOnly · Secure · SameSite=Strict · prefijo __Host-HttpOnly significa que el JavaScript de la página no puede leerla. Un robo de
token deja de ser posible porque no hay nada que robar en el navegador.
Qué hace cada pieza de esa cookie
Sección titulada «Qué hace cada pieza de esa cookie»HttpOnly |
el script de la página no la ve |
Secure |
no viaja fuera de HTTPS |
SameSite=Strict |
no se manda en peticiones que vienen de otro sitio, que es lo que corta el CSRF |
__Host- |
el navegador la ata a este dominio exacto y a /; un subdominio no puede sobrescribirla |
⚠️
__Host-exigeSecure, y el navegador rechaza en silencio una cookie__Host-que no lo lleve. No hay error, no hay aviso: el acceso parece correcto y la sesión no se guarda nunca — entrar, y volver al login. Por eso el prefijo solo se pone cuando la conexión lo admite (localhost, o HTTPS real mirandoX-Forwarded-Proto). Si tu proxy no manda esa cabecera, no habrá prefijo, y conviene saberlo antes de perder una tarde.
Las llamadas pasan por el propio panel
Sección titulada «Las llamadas pasan por el propio panel»Las pantallas no llaman al backend: llaman a /admin/api/backend/*, que es una
ruta del panel. Ahí, en el servidor, se lee la cookie, se saca el token y se
reenvía la petición.
Esto tiene tres consecuencias que valen más que la comodidad que quita:
- Deja de hacer falta CORS. El navegador habla con su propio origen. No hay
ADMIN_CORSque ajustar ni orígenes que autorizar. - El backend no queda expuesto al navegador. Solo el panel le habla.
- Las rutas están en una lista blanca del servidor. El proxy no reenvía a donde le digan: reenvía a lo que tiene permitido. Un parámetro manipulado no convierte el panel en un puente hacia otra máquina.
El cliente es nuestro, y por qué
Sección titulada «El cliente es nuestro, y por qué»@pcreative/admin-client. Sin dependencias.
Antes había un SDK de terceros y se cambió tras mirar el uso real: de las llamadas del panel, la mitad larga eran una petición HTTP a pelo y el resto se repartía en una treintena de métodos. A cambio de ese envoltorio delgado, decenas de ficheros del panel quedaban atados a una dependencia externa y a su forma de nombrar las cosas.
Lo que sí hubo que replicar exactamente es el formato de la petición, porque eso no es una decisión de diseño: es lo que el backend espera al otro lado.
- La consulta se serializa con corchetes:
filtro[campo]=valor, y las listas indexadas,ids[0]=a&ids[1]=b. - Los nulos se omiten.
- Las cookies viajan.
- El error lleva el mensaje del backend, no el genérico del código de estado.
Equivocarse en cualquiera de esas cuatro no da ningún error: se manda un filtro que no casa con nada, el backend responde 200 con una lista vacía, y la pantalla dice «no hay productos» con el catálogo lleno. Por eso el cliente lleva pruebas sobre el formato y no sobre que «funcione».
Un panel, varias tiendas
Sección titulada «Un panel, varias tiendas»El backend al que se habla se resuelve según el tema activo: al activar un tema y recargar, el panel pasa a hablar con el backend de ese tema.
La sesión es de cada backend, así que al cambiar de tienda hay que volver a entrar. No es un descuido: que una sesión sirviera para varias tiendas convertiría el panel en una llave maestra.
Para desplegarlo
Sección titulada «Para desplegarlo»En Los paneles y sus dominios está
la configuración de Apache con subdominios y sin ellos. Lo único que no se puede
olvidar es X-Forwarded-Proto, por lo dicho arriba.