Il contesto
Per un admin irrobustito, ho legato il token JWT a un'impronta del browser (fingerprint) per limitare il furto di token. A ogni richiesta, si riverifica l'impronta.
Il sintomo
Utenti disconnessi dopo pochi minuti, in modo casuale. Token però non scaduto.
La causa
Il fingerprint includeva componenti instabili:
// Mauvais : ces valeurs bougent
const fp = hash([
  navigator.userAgent,
  window.innerWidth + 'x' + window.innerHeight, // change au resize !
  navigator.language,
]);
innerWidth/innerHeight cambia al minimo ridimensionamento → l'hash non corrisponde più → rifiuto.
La soluzione
Mantenere solo componenti stabili, e verificare con tolleranza:
const fp = hash([
  navigator.userAgent,
  navigator.language,
  screen.width + 'x' + screen.height, // resolution ecran, pas la fenetre
  navigator.platform,
]);
public function isFingerprintValid(array $tokenFp, array $requestFp): bool
{
    foreach (['ua', 'platform'] as $key) {
        if (($tokenFp[$key] ?? null) !== ($requestFp[$key] ?? null)) {
            return false;
        }
    }
    return true; // les composants secondaires ne bloquent pas
}
Cosa ne ricavo
  • Un fingerprint = unicamente componenti stabili.
  • Uguaglianza stretta su dati volatili = bug casuali garantiti.
  • Il fingerprint completa, non sostituisce, le buone pratiche JWT.