Bouw een eenvoudige wachtwoordsterktecontrole

Directe feedback geven is het ding op dit moment. Waarom zou u zich beperken tot het controleren van gebruikersnamen en e-mailadressen? Waarom zou u dit niet uitbreiden om snel visuele feedback te geven over de sterkte van het wachtwoord dat de gebruiker heeft ingevoerd? Vandaag gaan we bekijken hoe u een eenvoudige wachtwoordsterktechecker kunt maken met behulp van de jQuery-bibliotheek, reguliere expressies en een eenvoudig algoritme.


Een woord van de auteur

Zoals de meeste beveiligingsexperts u zullen vertellen, is de gebruiker altijd de zwakste schakel. De veiligste systemen zijn kwetsbaar wanneer een gebruiker een extreem slecht geadviseerd wachtwoord kiest. Met dat in gedachten lijkt de recente trend snelle feedback te geven aan de gebruiker over de sterkte van het wachtwoord, zodat de gebruiker het wachtwoord kan uitbreiden of wijzigen om het veiliger te maken.

Vandaag gaan we de jQuery-bibliotheek, een reeks reguliere expressies en een heel eenvoudig algoritme gebruiken om een ​​basiscontrole voor wachtwoordsterkte te maken. Geïnteresseerd? Laten we meteen beginnen! Hier is een demo van wat we vandaag proberen te bouwen:

Ontwerpdoelen

Onze ontwerpdoelen voor deze specifieke functionaliteit zijn relatief klein.

  • Geef visuele feedback aan de gebruiker over de sterkte van zijn wachtwoord.
  • De feedback moet onmiddellijk zijn. Dit betekent dat je niet op een knop hoeft te klikken om de sterkte te testen.
  • De triggergebeurtenis kan een van de toetsenbordgebeurtenissen zijn. Ik heb keyup gekozen omdat dit het meest geschikt is voor onze specifieke behoefte.
  • Voor de visuele feedback is het bijzonder moeilijk om de tekst alleen al, hoewel nuttig, te wijzigen. Ik heb ervoor gekozen de achtergrondkleuren ook te wijzigen om de aandacht van de gebruiker hierop te vestigen.
  • Geef extra kwantificeerbare feedback, zodat de gebruiker weet op welke afdelingen het wachtwoord onvoldoende kracht heeft en hoe het kan worden verbeterd.

Nu we onze behoeften voldoende hebben uitgedacht, kunnen we doorgaan naar de volgende fase.

Plan van aanpak

We zullen nu beslissen over de volgorde van de afzonderlijke stappen die moeten worden uitgevoerd.

  • Sluit de gebeurtenishandler aan op de keyup gebeurtenis van het invoervak.
  • Laat de gebeurtenishandler de invoer controleren maar delegeer al het andere naar individuele hulpmethoden.
  • De hulpmethoden moeten ervoor zorgen dat de invoer wordt ontleed en geanalyseerd, de complexiteit wordt berekend en de resultaten worden afgedrukt.
  • Zorg ervoor dat de gebeurtenishandler alleen de hulpermethoden afvuurt als de lengte van de invoer groter is dan het verwachte minimum om CPU-cycli bij ongeldige vermeldingen niet te verspillen.
  • Stuur de controle terug naar de gebeurtenishandler voor het geval er iets anders moet gebeuren.

Het algoritme

In het belang van het overzichtelijk en aanspreekbaar houden van dit bericht, heb ik besloten om te gaan met een zeer basaal algoritme. Het algoritme analyseert de reeks, geeft bonussen voor extra lengte, aanwezigheid van cijfers, symbolen en hoofdletters en straffen voor letter- of cijferinvoer. We gaan niet kijken naar het vergelijken van gemeenschappelijke patronen of het controleren van de invoer tegen een woordenboek, omdat dit buiten de reikwijdte van het artikel valt. Als de belangstelling piekt, kan ik hierover in de toekomst een artikel schrijven.

Eerst controleren we de lengte van de invoerreeks. Als het groter is dan de minimumlengte, geef het dan een basisscore van 50. Anders maakt het 0. Volgende itereer door elk teken van de reeks en controleer of het een symbool, cijfer of hoofdletter is. Als dat zo is, noteer het dan.

Controleer vervolgens hoeveel extra tekens de tekenreeks heeft, boven het aanbevolen minimum en geef een bonus voor elk teken. Geef ook een bonus als de reeks een combinatie van hoofdletters, cijfers en symbolen of alle drie bevat. Geef ook een bonus voor ieders aanwezigheid.

Controleer of de string alleen kleine letters of cijfers bevat en zo ja, bestraft.

Tel alle getallen bij elkaar op en bepaal de sterkte van het wachtwoord.

Dat is lang en kort van het algoritme. Het gaat niet extreem soepel maar het haalt veel slechte wachtwoorden op. Je zult dit beter begrijpen als we het in code zien.

Core Markup

De HTML-markering van de demopagina ziet er als volgt uit:

   Simple Password Strength Checker - door Siddharth voor NetTuts      

Maak een eenvoudige wachtwoordsterktecontrole

door Siddharth voor de lieve mensen van Net Tuts

Voer uw wachtwoord in om visuele feedback te krijgen over de sterkte van uw wachtwoord.

Ik verzeker je, ik steel je wachtwoord niet. Het formulier verzendt niet. Je kunt door de bron kijken als je achterdochtig bent. :)

Voer een willekeurige waarde in
Uitsplitsing van punten

Negeer alle gebruikelijke markup. Let op het invoerelement met een ID van inputPassword, het div element met een ID van ingewikkeldheid welke de complexiteit toont van het wachtwoord en div element met een ID van gegevens die de verdeling van punten toont.

We hebben ook de jQuery-bibliotheek en ons eigen scriptbestand opgenomen. Extra punten als u de naam van ons scriptbestand op prijs stelt.

CSS-styling

lichaam font-family: "Lucida Grande", "Verdana", sans-serif;  h1 font-size: 30px; opvulling: 0; marge: 0;  h2 font-size: 18px; opvulling: 0; marge: 0 5px 30px 0;  invoer width: 288px; hoogte: 30 px; marge: 50px 0 0 0; opvulling: 3px 5px; lettertypegrootte: 22px; font-family: "Lucida Grande", "Verdana", sans-serif;  #container width: 820px; marge links: auto; marge-rechts: auto; opvulling: 50px 0 0 0;  .block width: 300px; marge: 0 auto 0 auto;  #complexity, #results width: 300px; opvulling: 3px 0; hoogte: 20 px; kleur: # 000; lettergrootte: 14 px; text-align: center;  #results marge: 30px 0 20px 0;  .default background-color: #CCC; .weak background-color: # FF5353; .strong background-color: # FAD054; .stronger background-colour: # 93C9F4;  .sterkste achtergrondkleur: # B6FF6C; span.value font-weight: bold; zweven: rechts; 

Alleen ketelplaat-CSS voor lay-outs en typografie. We hebben een aantal klassen aan de onderkant voor elke individuele sterkte. We zullen ze toevoegen aan de elementen wanneer dat nodig is.

JavaScript-implementatie

Nu we beschikken over een solide framework en een aantal basisstijlen, kunnen we beginnen met het coderen van de vereiste functionaliteit. Merk op dat we uitgebreid gebruik maken van jQuery. U kunt zo nodig een koppeling maken naar het CDN van Google.

Variabelen en afhandeling van gebeurtenissen

Omdat veel nummer jongleren zal gaan, hebben we een aantal variabelen nodig om de waarden vast te houden. Omdat het een demo is en geen productiecode, had ik besloten om de variabelen als globaal te verklaren en ze via de hulpmethoden te gebruiken in plaats van ze intern te verklaren en ze vervolgens door te geven aan de functies.

 var strPassword; var charPassword; var complexity = $ ("# complexity"); var minPasswordLength = 8; var baseScore = 0, score = 0; var num = ; num.Excess = 0; num.Upper = 0; num.Numbers = 0; num.Symbols = 0; var bonus = ; bonus.Excess = 3; bonus.Upper = 4; bonus.Nummers = 5; bonus.Symbolen = 5; bonus.Combo = 0; bonus.FlatLower = 0; bonus.FlatNumber = 0;

De variabelenamen zijn vrij standaard, maar ik zou toch een overzicht geven. strPassword houdt de waarde van het invoervak ​​vast, charPassword is een array met elk teken van de tekenreeks, ingewikkeldheid bevat een verwijzing naar het div-element. We definiëren ook de minimale wachtwoordlengte, score en de basisscore.

We maken een snelle hash voor het aantal extra tekens, hoofdletters, cijfers en symbolen. We doen hetzelfde voor de bonussen. De num hash bevat het aantal tekens terwijl de bonus hash bevat de bonus-multipliers. Je kunt alleen individuele variabelen maken, maar ik vind dat dit er schoner uitziet.

Vergeet niet om de gebeurtenishandler aan het evenement te koppelen.

 $ ("# inputPassword"). bind ("keyup", checkVal);

checkVal is de gebeurtenishandler die we in slechts een klein beetje zullen maken.

De gebeurtenishandler

function checkVal () if (charPassword.length> = minPasswordLength) baseScore = 50; analyzeString (); calcComplexity ();  else baseScore = 0;  outputResult (); 

We controleren eerst de lengte van de invoerreeks. Als het groter is dan of gelijk aan de minimale opgegeven lengte, kunnen we doorgaan. We stellen de basisscore in op 50 en noemen de hulpmethoden die zorgen voor analyse van de reeks en berekening van de complexiteit.

Als het minder is dan de verwachte lengte, stellen we de basisscore in op 0.

We noemen dan de outputResult functie die zorgt voor het begrijpen van de berekende berekeningen. We zullen later zien hoe het werkt.

Analyse van de invoer

function analysisString () for (i = 0; i 

Dit ziet er misschien een beetje ingewikkeld uit maar ik beloof het je, het is alleen vanwege de reguliere expressies. Laten we de code voor een deel bekijken.

Eerst moeten we de samenstelling van de string in kwestie achterhalen. Net als in, moeten we uitzoeken of de reeks hoofdletters, cijfers of symbolen bevat en, zo ja, hoeveel daarvan aanwezig zijn. Met dit in gedachten, herhalen we de karakterarray en controleren we alle tekens om het type te zien. De wedstrijd methode laat ons een string matchen met een reguliere expressie. Als je net begint met reguliere expressie, raad ik je aan om Vasili's geweldige artikel hier te lezen.

Vervolgens bepalen we het verschil tussen de lengte van de invoerreeks en de opgegeven minimale lengte van het wachtwoord. Dit geeft ons het overtollige aantal personages om mee te spelen.

We controleren dan of de string hoofdletters, cijfers en symbolen bevat. Als dat zo is, geef dan een bonus. We controleren ook of het combinaties van twee heeft en een kleinere bonus als dat het geval is.

Ten slotte controleren we of een tekenreeks leeg is: of deze alleen kleine letters of alleen cijfers bevat. We controleren dit met een reguliere expressie en bestraffen het wachtwoord voor deze oefening.

Bereken de complexiteit

function calcComplexity () score = baseScore + (num.Excess * bonus.Excess) + (num.Upper * bonus.Upper) + (num.Numbers * bonus.Numbers) + (num.Symbols * bonus.Symbols) + bonus .Combo + bonus. FlatLower + bonus. FlatNumber; 

Gewoon een simpele toevoeging. We voegen de basisscore toe aan het product van het aantal overtollige tekens en de multiplier. Hetzelfde geldt voor hoofdletters, cijfers en symbolen. We voegen vervolgens een bonus toe voor combinaties, indien aanwezig, en voegen boetes toe als de reeks plat is.

De gebruikersinterface bijwerken

Nu alle berekeningen achter de rug zijn, kunnen we de gebruikersinterface bijwerken om de wijzigingen te weerspiegelen. Hier zijn alle staten.

function outputResult () if ($ ("# inputPassword"). val () == "") complexity.html ("Voer een willekeurige waarde in"). addClass ("default");  else if (charPassword.length < minPasswordLength)  complexity.html("At least " + minPasswordLength+ " characters please!").addClass("weak");  else if (score<50)  complexity.html("Weak!").addClass("weak");  else if (score>= 50 && score<75)  complexity.html("Average!").addClass("strong");  else if (score>= 75 && score<100)  complexity.html("Strong!").addClass("stronger");  else if (score>= 100) complexity.html ("Secure!"). AddClass ("strongest"); 

Niets bijzonders hier, maar we zullen het regel voor regel doornemen.

We controleren eerst of de invoer leeg is. Zo ja, verander de tekst van het resultaat en voeg een toe standaard klasse om de achtergrondkleur terug te zetten naar het originele grijs.

Als het minder is dan de minimum opgegeven lengte, veranderen we de tekst dienovereenkomstig en voegen een toe zwak klasse, dus de achtergrond is rood. We doen hetzelfde als de totale score lager is dan 50, maar de tekst wijzigen in zwak.

Naarmate de score toeneemt, veranderen we de tekst dienovereenkomstig en voegen we de nodige klassen toe. U kunt de basisscores voor elke beoordeling wijzigen. Ik stopte gewoon onwetenschappelijke waarden in om de demo aan de gang te krijgen.

De gedetailleerde uitsplitsing bijwerken

Nu het hoofdresultaat is bijgewerkt, kunnen we nu kijken naar het bijwerken van de statistieken.

function outputResult () // Previous Code $ ("# details"). html ("Basisscore:"+ baseScore +""+"
Lengte Bonus:"+ (num.Excess * bonus.Excess) +" ["+ num.Excess +" x "+ bonus.Excess +"] "+"
Hoofdletters bonus:"+ (aantal.Upper * bonus.Upper) +" ["+ aantal.Upper +" x "+ bonus.Upper +"] "+"
Nummer bonus: "+ (num.Numbers * bonus.Numbers) +" ["+ num.Numbers +" x "+ bonus.Numbers +"]"+"
Symboolbonus: "+ (num.Symbols * bonus.Symbols) +" ["+ num.Symbols +" x "+ bonus.Symbols +"]"+"
Combinatiebonus: "+ bonus.Combo +""+"
Kleine straf: "+ bonus.FlatLower +""+"
Nummers alleen penalty: "+ bonus.FlatNumber +""+"
Totale score: "+ score +""

Dit deel is niet zo verwarrend als het lijkt. Laat het me uitleggen.

In plaats van alleen de afzonderlijke waarden bij te werken voor de gedetailleerde resultaten, heb ik mijn toevlucht genomen tot het bijwerken van de volledige HTML-waarde van de container. Ik weet dat het traag gaat worden als een aantal van deze boxen optellen, maar elk afzonderlijk element openen en vervolgens de waarde ervan bijwerken voor een kleine demo leek nogal contraproductief. Loop hier maar met mij mee.

Dit is net als het injecteren van normale HTML in een element, behalve dat we een paar variabelen in de kolom hebben geplaatst om de details onmiddellijk te kunnen bijwerken. Elke waarde krijgt een waarde klas om het vet te maken. We geven ook het aantal speciale tekens weer en het is multipler, zodat de gebruiker kan bepalen welke elementen meer weightage krijgen.

Een paar aanpassingen

Op dit moment zijn er 2 bugs die verschijnen.

  • Als u een lang wachtwoord invoert en vervolgens het tekstvak wist, veranderen de achtergrondkleuren niet meer.
  • In hetzelfde scenario worden de details van de punten niet bijgewerkt zoals het zou moeten.

We pakken ze één voor één aan.

Voor de eerste fout is de oorzaak meestal dat we niet alle andere klassen verwijderen. Dit zou geen probleem zijn als de laatst toegevoegde klassen voorrang krijgen op andere. Helaas is het niet waar. Hier is een snelle oplossing.

function outputResult () if ($ ("# inputPassword"). val () == "") complexity.html ("Voer een willekeurige waarde in"). removeClass ("weak strong strong strongestestest"). addClass ("default "); else if (charPassword.length < minPasswordLength) complexity.html("At least " + minPasswordLength+ " characters please!").removeClass("strong stronger strongest").addClass("weak"); else if (score<50) complexity.html("Weak!").removeClass("strong stronger strongest").addClass("weak"); else if (score>= 50 && score<75) complexity.html("Average!").removeClass("stronger strongest").addClass("strong"); else if (score>= 75 && score<100) complexity.html("Strong!").removeClass("strongest").addClass("stronger"); else if (score>= 100) complexity.html ("Secure!"). AddClass ("strongest"); // Updatecode voor details

U vraagt ​​waarschijnlijk waarom we niet elke klas hier verwijderen. Het antwoord is simpel: we profiteren van een van de belangrijkste kenmerken van CSS: cascading. Als u de volgorde van declaratie van elke klasse in het CSS-bestand noteert, zult u dat merken standaard komt de eerste en sterkste komt het laatste wat betekent dat als een element de sterkste klasse heeft dit voorrang op eventuele wijzigingen aangebracht door een klasse erboven. We zullen dus alleen klassen moeten verwijderen die zich onder de betreffende klasse bevinden. Bijvoorbeeld om een ​​element te hebben sterk, we zullen het moeten verwijderen sterker en sterkste klassen.

De reden dat de tweede fout bestaat, is te wijten aan het feit dat de individuele variabelen niet worden gereset als zich een nieuwe gebeurtenis voordoet. Ze dragen ook over naar het volgende evenement. Om dit op te lossen, creëren we een snelle functie die alle relevante variabelen opnieuw initialiseert en deze toevoegt checkVal gebeurtenishandler, zodat deze wordt aangeroepen telkens wanneer de tekst van het invoervak ​​wordt bijgewerkt.

function init () strPassword = $ ("# inputPassword"). val (); charPassword = strPassword.split (""); num.Excess = 0; num.Upper = 0; num.Numbers = 0; num.Symbols = 0; bonus.Combo = 0; bonus.FlatLower = 0; bonus.FlatNumber = 0; baseScore = 0; score = 0; 
function checkVal () init (); // Andere code

beperkingen

Als je een beetje met de demo hebt gespeeld, zul je dat merken Pa $$ W0rd $ verschijnt als een veilig wachtwoord terwijl het in feite vrij snel zal worden verbroken. Dit komt door de eenvoud van ons algoritme hier. We controleren niet op vervanging van personages. Of gemeenschappelijke wachtwoorden of patronen voor die kwestie. Het doen van dergelijke dingen zou de moeilijkheidsgraad van deze tutorial vergroten en tegelijkertijd de toegankelijkheid verminderen, die ik beide niet wilde hebben voor dit specifieke artikel.

Dit is bedoeld als basiscontrole voor de sterkte van een wachtwoord. Als u het moet verbeteren, kunt u waarschijnlijk een paar meer reguliere expressies toevoegen om te controleren op patronen en tekenherhaling en de resultaten dienovereenkomstig afstemmen.

Het opzoeken van de invoer tegen een woordenboek valt echt buiten het bestek van dit artikel en vereist ofwel een enorm woordenboek dat is gedownload naar de clientzijde of dat is gekoppeld aan een server side-systeem om dat te doen. Nogmaals, ik wilde deze beide echt deze keer vermijden.

Conclusie

En daar heb je het: hoe een gebruiksvriendelijke functionaliteit toe te voegen, de mogelijkheid om de gebruiker de sterkte te laten weten van een wachtwoord dat hij zojuist heeft ingevoerd, aan uw projecten. Hopelijk heb je deze tutorial interessant gevonden en dit was nuttig voor jou. Voel je vrij om deze code elders in je projecten en hier te gebruiken als je in de problemen raakt.

Vragen? Leuke dingen om te zeggen? Kritiek? Klik op het gedeelte Opmerkingen en laat een opmerking achter. Happy codering!

  • Volg ons op Twitter of abonneer je op de Nettuts + RSS Feed voor de beste tutorials voor webontwikkeling op internet.