Repository navigation
Added
- Driver de caché Redis/Valkey seleccionable con
CACHE_DRIVER=file|redis(defaultfile, sin cambios si no se configura):CacheInterfaceconFileCache,NullCachey el nuevoRedisCache(phpredis);Userrecibe la caché por constructor (?CacheInterface, por defectoappCache()).App\Lib\Redis\RedisConnector: timeouts cortos, auth por ACL (REDIS_USERNAME/REDIS_PASSWORD),REDIS_DB, prefijo validado y una sola conexión (o un solo fallo) por petición.- Claves
{REDIS_PREFIX}{CACHE_VERSION}:cache:{key}con TTL nativo; subirCACHE_VERSIONinvalida en bloque sinFLUSHDB.unserializeconallowed_classes=false. - Con Redis caído, sin la extensión o con credenciales erróneas,
appCache()devuelveNullCache: la app responde 200 y deja una sola línea en el log, sin credenciales. - Nuevas variables:
CACHE_DRIVER,CACHE_VERSION,REDIS_HOST,REDIS_PORT,REDIS_USERNAME,REDIS_PASSWORD,REDIS_DB,REDIS_PREFIX,REDIS_CONNECT_TIMEOUT,REDIS_READ_TIMEOUT. docs/redis/redis.conf.example: bind local, usuariodefaultdesactivado, usuario ACL sin@dangerous/@admin,maxmemory+volatile-lru;ext-rediscomosuggestencomposer.json.
- Sesiones PHP en Redis con
SESSION_DRIVER=file|redis(defaultfile), enapp/Config/session.php:- Handler nativo de phpredis con locking activo (CSRF rotativo y peticiones AJAX concurrentes), claves
{REDIS_PREFIX}sess:{id}y TTLSESSION_TIMEOUT + 300. session.use_strict_mode=1solo con el driver Redis: rechaza IDs de sesión inventados por el cliente.- Si Redis no responde al arrancar, la sesión vuelve a archivos (una línea en el log, nunca HTTP 500).
- Handler nativo de phpredis con locking activo (CSRF rotativo y peticiones AJAX concurrentes), claves
- Límite de intentos de login por IP (
App\Service\LoginThrottle, RedisINCR+EXPIRE NXenMULTI, ventana fija), detrás deLOGIN_IP_THROTTLE_ENABLED(defaultfalse):- Independiente del bloqueo por usuario de MySQL; la IP se guarda como SHA-256 y, si Redis falla, deja pasar (el bloqueo por usuario sigue protegiendo las cuentas).
- Nuevas variables:
SESSION_DRIVER,LOGIN_IP_THROTTLE_ENABLED,LOGIN_IP_MAX_ATTEMPTS(20),LOGIN_IP_WINDOW(900 s).
docs/redis/por-que-mysql.md: justificación de por quélogin_attemptsyuser_sessionsse quedan en MySQL (con Redis caído fallarían abiertos).- 48 tests nuevos (143 en total) contra Redis real (DB 15, prefijo
encphp_test:, nuncaFLUSHDB): contrato de caché compartido porFileCacheyRedisCache, degradación, invalidación de las 8 escrituras deUser(tests/Integration/UserCacheRedisTest.php), almacenamiento de sesiones (SessionStorageTest) y límite por IP (LoginThrottleTest). Sin Redis salen como skipped, salvoREDIS_REQUIRED=true(CI), donde fallan. - CI: servicio Valkey con
--requirepassy extensiónredisensetup-php.
Changed
.gitignoreignoradocs/redis/redis.conf(la config real lleva la clave del usuario ACL); solo se versiona el.example.appCache()devuelveCacheInterface; la caché deshabilitada o con directorio no escribible usaNullCacheen vez de unFileCacheapagado.
Full Changelog
https://github.com/jandrescodes/Encriptacion_PHP/blob/master/CHANGELOG.md