jQuery: Come valutare la forza di una password?

In questo articolo vedremo come sviluppare un plugin in grado di misurare la “forza” di una password, con una barra di avanzamento che che mostrerà in live la validità della stringa che stiamo digitando. Il risultato finale sarà come quello mostrato in questa pagina di esempio.

Avrai già visto una cosa del genere diverse volte e oggi scoprirai come realizzarne una da zero, ti interessa?

Download

Preparare la pagina

Tanto per iniziare dalle cose semplici creiamo il file index.html nel quale dichiareremo un form con un campo password.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Verifica affidabilità password</title>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
    //qui scriveremo il codice jQuery
    });
    </script>
    <style>

</head>

<body>
    <form action="?" method="post">
   	 Inserisci password:<br />
   	 <input type="password" name="password" id="password" /><br /><br />
   	   	 <input type="submit" value="invia" />
    </form>
</body>
</html>

Come vedi ho già incluso jQuery ed ho predisposto la funzione document ready nella quale andremo a scrivere il codice necessario per il funzionamento del nostro plugin.

Ora, sotto il campo password, andiamo ad inserire gli elementi che andranno a rappresentare la barra di avanzamento.

<div id="result">
   <div id="bar"></div>
</div>

Nel nostro caso #result rappresenta il contenitore della barra, mentre #bar la barra vera e propria.

Definiamo ora lo stile di #result in questo modo

#result
   	 {
   		 border: 1px solid gray;
   		 padding: 2px;
   		 width: 200px;
   		 height: 10px;
   	 }

La nostra pagina index.html ora si presenta così:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Verifica affidabilità password</title>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
    //qui scriveremo il codice jQuery
    });
    </script>
    <style>
   	 #result
   	 {
   		 border: 1px solid gray;
   		 padding: 2px;
   		 width: 200px;
   		 height: 10px;
   	 }

    </style>
</head>

<body>
    <form action="?" method="post">
   	 Inserisci password:<br />
   	 <input type="password" name="password" id="password" /><br /><br />
   	 <div id="result">
   		 <div id="bar"></div>
   	 </div>
   	 <br />
   	 <input type="submit" value="invia" />
    </form>
</body>
</html>

Quali sono le caratteristiche di una buona password?

Prima di iniziare a sviluppare il nostro plugin domandiamoci quali sono le caratteristiche che dovrebbe avere una buona password.

Innanzitutto deve essere una stringa di una certa lunghezza, variata, imprevedibile e ovviamente priva di senso compiuto. In questo quadro la presenza di maiuscole, minuscole, numeri e soprattutto caratteri speciali ($?%{!….) contribuisce ad aumentarne la robustezza.

Come tenere conto in pratica di queste caratteristiche?

Quello che ho pensato é di mettere in palio un massimo di 100 punti. Ad ogni caratteristica soddisfatta verranno assegnati dei punti in una quantità variabile a dipendenza dell’importanza che vogliamo attribuire a ciascuna caratteristica, in questo modo:

  • Minuscole: 10 punti
  • Maiuscole: 10 punti
  • Numeri: 10 punti
  • Caratteri speciali: 20 punti
  • Almeno quattro caratteri speciali: 30 punti
  • Lunghezza della stringa che supera i 12 caratteri: 20 punti

Inoltre ho stabilito che, al di sotto dei 6 caratteri, la password non viene nemmeno valutata (0 punti in ogni caso).

Passiamo al codice

Iniziamo a sviluppare il nostro plugin all’interno della funzione document ready.

 var width = $('#result').width();
    var actRate = 0;
    $('#bar').css({'height':'100%','width':0,'background-color':'red'});

Come prima cosa vado a misurare la larghezza di #result (noi l’abbiamo impostata tramite css a 200px). Perché facciamo questo?

La barra di avanzamento dovrà essere dimensionata in proporzione alla larghezza di #result.

Poniamo che la mia password valga 50 punti. Se #result é largo 100px, #bar dovrà essere dimensionata a 50px; se #result é largo 300px, #bar dovrà avere una dimensione di 150px.

Dunque per poter applicare correttamente la proporzione dovremo conoscere la larghezza di #result (che potremo così dimensionare comodamente da css senza dovreci preoccupare di altro).

La necessità della seconda variabile (actRate) la vedremo alla fine.

Con l’ultima riga applichiamo lo stile alla barra di avanzamento. Definiamo l’altezza al 100% in modo che si adatterà a qualsiasi altezza che imposteremo per il suo contenitore (#result).

La larghezza iniziale ovviamente a 0px ed infine il colore di background iniziale sarà rosso (anche se ancora non si vede, appena inizieremo ad animarlo si vedrà).

Definiamo ora all’interno di variabili le espressioni regolari che ci serviranno per valutare le caratteristiche della password:

var lowerCase = /[a-z]+/;  //minuscole
var upperCase =  /[A-Z]+/; //maiuscole
var numbers = /[0-9]+/; //numeri
var specialChars = /[\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\072\073\074\075\076\077\100\133\135\137\173\174\175]+/;  //caratteri speciali
var specialCharsBonus = /[\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\072\073\074\075\076\077\100\133\135\137\173\174\175]{4,}/; // almeno quattro caratteri speciali

Come vedi ho espresso i caratteri speciali in forma di ottali per evitare che gli stessi mi facessero casini all’interno dell’espressione regolare.

Ed ora arriviamo al cuore del nostro plugin.

A questo punto dovremo, ad ogni rilascio di tasto (keyup):

  • Leggere la stringa contenuta nel campo password
  • assegnarle un punteggio in base alle caratteristiche
  • se il punteggio é cambiato, modificare la dimensione della barra di avanzamento

Iniziamo dunque con l’intercettare l’evento keyup nel campo password. Al verificarsi di questo evento leggiamo il contenuto del campo e lo inseriamo nella variabile pwd. In seguito azzeriamo la variabile rate che conterrà il punteggio assegnato alla stringa.

$('#password').keyup(function(){
   var pwd = $('#password').val()
   var rate = 0;

A questo punto possiamo eseguire tutti i controlli che abbiamo stabilito

if(pwd.length >= 6) // la password viene valutata a partire da una lunghezza minima di 6 caratteri
{
    if(lowerCase.test(pwd))//caratteri minuscoli
    {
        rate += 10;
    }
    if(upperCase.test(pwd))//caratteri maiuscoli
    {
        rate += 10;
    }
    if(numbers.test(pwd))//numeri
    {
        rate += 10;
    }
    if(specialChars.test(pwd))//caratteri speciali
    {
    rate += 20;
    }
    if(specialCharsBonus.test(pwd))//almeno 4 caratteri speciali
    {
    rate += 30;
    }
    if(pwd.length > 12)//striga che supera i 12 caratteri
    {
        rate += 20;
    }
}

Alla fine di questi controlli, rate conterrà il punteggio ottenuto dalla password.

Possiamo dunque passare a modificare la dimensione della barra di avanzamento.

Come modificare la dimensione (e il colore) della barra di avanzamento?

Utilizzeremo il metodo animate() alla quale passeremo:

  • La dimensione che dovrà raggiungere la barra
  • La durata dell’animazione
  • La funzione nella quale descriveremo quello che deve succedere una volta terminata l’animazione (nel nostro caso l’eventuale cambiamento di colore della barra)

Ma prima di tutto dovremo rendere proporzionale la barra alla dimensione del contenitore.

Per farlo ci basterà moltiplicare il punteggio per la larghezza del contenitore (che abbiamo salvato precedentemente nella variabile width) diviso 100.

var barWidth = rate * (width / 100);

Ed ora possiamo animare la nostra barra:

$('#bar').animate({
    width: barWidth
    },500, function(){
               // terminata l’animazione modificheremo, se fosse il caso, il colore della barra
         });

I colori della barra

Ho stabilito (arbitrariamente) quattro colori nella barra di avanzamento:

  • Rosso -> da 0 a 25 punti
  • Arancio -> da 25 a 50 punti
  • Verde chiaro da 50 a 75 punti
  • Verde oltre i 75 punti

Quindi, ad animazione terminata, eseguiremo i seguenti controlli all’interno della funzione:

if(rate < 25)
   {
    $('#bar').css('background-color', 'red');
   }
   if(rate >= 25 && rate < 50)
   {
    $('#bar').css('background-color', '#FF7F2A');
   }
   if(rate >= 50 && rate < 75)
   {
    $('#bar').css('background-color', '#AAFF55');
   }
   if(rate >= 75)
   {
    $('#bar').css('background-color', 'green');
   }

Il codice completo si presenta così:

	$(document).ready(function(){

   	 var width = $('#result').width();
   	 var actRate = 0;
   	 $('#bar').css({'height':'100%','width':0,'background-color':'red'});

   	 var lowerCase = /[a-z]+/;
   	 var upperCase =  /[A-Z]+/;
   	 var numbers = /[0-9]+/;
   	 var specialChars = /[\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\072\073\074\075\076\077\100\133\135\137\173\174\175]+/;
   	 var specialCharsBonus = /[\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\072\073\074\075\076\077\100\133\135\137\173\174\175]{4,}/;
   	 $('#password').keyup(function(){
   		 var pwd = $('#password').val()
   		 var rate = 0;
   		 if(pwd.length >= 6)
   		 {
   			 if(lowerCase.test(pwd))
   			 {
   				 rate += 10;
   			 }
   			 if(upperCase.test(pwd))
   			 {
   				 rate += 10;
   			 }
   			 if(numbers.test(pwd))
   			 {
   				 rate += 10;
   			 }
   			 if(specialChars.test(pwd))
   			 {
   				 rate += 20;
   			 }
   			 if(specialCharsBonus.test(pwd))
   			 {
   				 rate += 30;
   			 }
   			 if(pwd.length > 12)
   			 {
   				 rate += 20;
   			 }

   		 }

   			 var barWidth = rate * (width / 100);
   			 $('#bar').animate({
   				 width: barWidth
   			 },500, function(){

   				 if(rate < 25)
   				 {
   					 $('#bar').css('background-color', 'red');
   				 }
   				 if(rate >= 25 && rate < 50)
   				 {
   					 $('#bar').css('background-color', '#FF7F2A');
   				 }
   				 if(rate >= 50 && rate < 75)
   				 {
   					 $('#bar').css('background-color', '#AAFF55');
   				 }
   				 if(rate >= 75)
   				 {
   					 $('#bar').css('background-color', 'green');
   				 }
   			 });

   	 });
    });

Ma attenzione, c’é un fastidioso errore. Fai tu stesso una prova con questa pagina che utilizza esattamente lo stesso codice che abbiamo appena visto. Prova ad inserire velocemente 6 caratteri (magari premento in continuazione sullo stesso tasto). Dovrai attendere alcuni secondi prima di vedere comparire la barra. Perché?

Semplice, l’animazione viene eseguita ad ogni keyup anche quando non é necessario. Dunque al primo keyup andrà da 0px a 0px, il secondo da 0px a 0px, eccetera. Nessuna variazione nella dimensione, ma impiegherà comunque 500 millisecondi ogni volta. Dunque premendo rapidamente sei volte su un tasto, avremo un ritardo di 2,5 secondi prima di poter vedere l’animazione.

Dobbiamo dunque fare in modo che l’animazione venga eseguita unicamente quando c’é una variazione del punteggio. Per fare questo utilizzeremo la variabile actRate che abbiamo definito all’inizio dello script con valore 0.

Ora semplicemente inseriamo questa condizione:

if(rate != actRate)
   {
    actRate = rate;
   var barWidth = rate * (width / 100);
    $('#bar').animate({
   	 width: barWidth
    },500, function(){

    if(rate < 25)
    {
   	 $('#bar').css('background-color', 'red');
    }
    if(rate >= 25 && rate < 50)
    {
   	 $('#bar').css('background-color', '#FF7F2A');
    }
    if(rate >= 50 && rate < 75)
    {
   	 $('#bar').css('background-color', '#AAFF55');
   }
    if(rate >= 75)
   {
    $('#bar').css('background-color', 'green');
   }
    });
   }

Come vedi la condizione per eseguire l’animazione é che actRate sia diversa da rate. Se lo é, actRate assume il valore di rate e l’animazione può essere eseguita.

Download

Conclusione

In questo articolo abbiamo visto come implementare un sistema per misurare le forza di una password utilizzando alcuni criteri che mi sono venuti in mente. Quello che vorrei fare ora é coinvolgere tutti voi nel processo di perfezionamento di questi criteri.

Secondo te:

  • Ho dato il giusto peso (punteggio) ai criteri ?
  • Ti vengono in mente altri criteri?

Inizio io: ho pensato che oltre un certo numero di caratteri (30? 40?), una password é sicura a prescindere da qualsiasi altro criterio e quindi prende il massimo dei punti. Sei daccordo? Dopo quanti caratteri può intervenrire questa regola?

Questo é il tipo di discussione che mi piacerebbe nascesse. E ti dico di più: se dovesse nascere un bel dibattito che ci porterà a trovare la “formula perfetta” ber una buona password, realizzerò la versione 2.0 di questo plugin che metterò a disposizione per il download sul repository di jQuery e che porterà la firma di Your Inspiration Web community.

Sarebbe la prima risorsa sviluppata con il contributo di tutta la comunità, che te ne pare?

Tag: , ,

L'autore

Maurizio è sposato con la triade PHP - MySql - Apache e, non pago, ha un'amante chiamata jQuery. Ha un blog dove cerca di descrivere nei minimi particolari sia la moglie che l'amante. La sua vera specialità è la realizzazione di gestionali complessi anche se non rifiuta mai un sito web. +

Sito web dell'autore | Altri articoli scritti da

Articoli correlati

Potresti essere interessato anche ai seguenti articoli:

10 commenti

Trackback e pingback

  1. Easy Form: Un piccolo fw per i tuoi form | Your Inspiration Web
    [...] integrato due plugin. Il primo é il “misuratore di forza di una password” che ho presentato in questo articolo.…