Обеспечение мгновенной обратной связи является неотъемлемой частью прямо сейчас. Зачем ограничиваться проверкой имен пользователей и адресов электронной почты? Почему бы не расширить это, чтобы обеспечить быструю визуальную обратную связь о надежности пароля, введенного пользователем? Сегодня мы рассмотрим, как создать простую проверку надежности пароля с использованием библиотеки jQuery, регулярных выражений и простого алгоритма.
Слово от автора
Как скажут вам большинство экспертов по безопасности, пользователь всегда является самым слабым звеном. Наиболее безопасные системы уязвимы, когда пользователь выбирает крайне опрометчивый пароль. Имея это в виду, недавняя тенденция, кажется, обеспечивает быструю обратную связь с пользователем относительно надежности пароля, так что пользователь может расширить или изменить пароль, чтобы сделать его более безопасным.
Сегодня мы собираемся использовать библиотеку jQuery, набор регулярных выражений и очень простой алгоритм для создания базовой проверки надежности пароля. Заинтересованы? Давайте начнем прямо сейчас! Вот демонстрация того, что мы пытаемся построить сегодня:
Цели дизайна
Наши цели дизайна для этой специфической функциональности относительно невелики.
- Обеспечьте визуальную обратную связь с пользователем относительно надежности его пароля.
- Обратная связь должна быть мгновенной. Это означает, что не нужно нажимать на кнопку, чтобы проверить прочность.
- Событие триггера может быть любым из событий клавиатуры. Я выбрал keyup, так как он наиболее подходит для наших конкретных потребностей.
- Что касается визуальной обратной связи, то изменение текста само по себе, хотя и полезно, но крайне отсутствует. Я также решил изменить цвета фона, чтобы привлечь внимание пользователя к этому.
- Предоставьте дополнительную количественную обратную связь, чтобы пользователь знал, в каких отделах пароль недостаточно надежен и как его можно улучшить.
Теперь, когда мы правильно выяснили наши потребности, мы можем перейти к следующему этапу.
План действий
Теперь мы определимся с порядком отдельных шагов, которые необходимо выполнить.
- Подключите обработчик событий к событию keyup в поле ввода.
- Пусть обработчик событий проверяет ввод, но делегирует все остальное отдельным вспомогательным методам.
- Вспомогательные методы должны позаботиться о разборе входных данных и их анализе, вычислении сложности и распечатке результатов.
- Убедитесь, что обработчик событий запускает вспомогательные методы, только если длина ввода больше ожидаемого минимума, чтобы не тратить циклы ЦП на недопустимые записи.
- Верните управление обработчику событий, если нужно что-то еще сделать.
Алгоритм
Чтобы сохранить эту запись лаконичной и доступной, я решил использовать очень простой алгоритм. Алгоритм анализирует строку, дает бонусы за дополнительную длину, наличие цифр, символов и букв верхнего регистра и штрафы за ввод только букв или цифр. Мы не будем рассматривать сопоставление общих шаблонов или проверку ввода по словарю, поскольку это выходит за рамки статьи. Если интерес пика, я могу сделать статью об этом в будущем.
Сначала мы проверяем длину входной строки. Если он больше минимальной длины, присвойте ему базовую оценку 50. В противном случае установите значение 0. Затем выполните итерацию по каждому символу строки и проверьте, является ли он символом, числом или буквой верхнего регистра. Если это так, запишите это.
Затем проверьте количество дополнительных символов в строке, превышающее рекомендуемый минимум, и дайте бонус каждому символу. Также предоставьте бонус, если строка содержит комбинацию букв верхнего регистра, цифр и символов или всех трех. Предоставьте бонус за каждое присутствие тоже.
Проверьте, содержит ли строка только строчные буквы или цифры, и если да, оштрафуйте.
Сложите все числа и определите надежность пароля соответственно.
Это длинный и короткий алгоритм. Это не очень учтивый, но он ловит много плохих паролей. Вы поймете это лучше, когда мы увидим это в коде.
Основная разметка
HTML-разметка демонстрационной страницы выглядит так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<!DOCTYPE html>
<html lang=»en-GB»>
<head>
<title>Simple Password Strength Checker — by Siddharth for NetTuts</title>
<link type=»text/css» href=»css/style.css» rel=»stylesheet» />
<script type=»text/javascript» src=»js/jquery.js»></script>
<script type=»text/javascript» src=»js/mocha.js»></script>
</head>
<body>
<div id=»container»>
<h1>Create a simple password strength checker</h1>
<h2 class=»bolded»>by Siddharth for the lovely folks at Net Tuts</h2>
<p>Type in your password to get visual feedback regarding the strength of your password.</p>
<p>I assure you, I am not stealing your passwords.
<div class=»block»>
<input id=»inputPassword»/>
<div id=»complexity» class=»default»>Enter a random value</div>
</div>
<div class=»block»>
<div id=»results» class=»default»>Breakdown of points</div>
<div id=»details»></div>
</div>
</div>
</body>
</html>
|
Не обращайте внимания на все обычные разметки. Обратите внимание на элемент input с идентификатором inputPassword , элементом div с идентификатором сложности, который показывает сложность пароля, и элементом div с идентификатором деталей, который показывает разбивку точек.
Мы также включили библиотеку jQuery и наш собственный файл скрипта. Дополнительные баллы, если вы цените имя нашего файла скрипта.
CSS Styling
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
body{
font-family: «Lucida Grande», «Verdana», sans-serif;
}
h1{
font-size: 30px;
padding: 0;
margin: 0;
}
h2{
font-size: 18px;
padding: 0;
margin: 0 5px 30px 0;
}
input{
width: 288px;
height: 30px;
margin: 50px 0 0 0;
padding: 3px 5px;
font-size: 22px;
font-family: «Lucida Grande», «Verdana», sans-serif;
}
#container{
width: 820px;
margin-left: auto;
margin-right: auto;
padding: 50px 0 0 0;
}
.block{
width: 300px;
margin: 0 auto 0 auto;
}
#complexity, #results{
width: 300px;
padding: 3px 0;
height: 20px;
color: #000;
font-size: 14px;
text-align: center;
}
#results{
margin: 30px 0 20px 0;
}
.default{background-color: #CCC;}
.weak{background-color: #FF5353;}
.strong{background-color: #FAD054;}
.stronger{background-color: #93C9F4;
.strongest{background-color: #B6FF6C;}
span.value{
font-weight:bold;
float: right;
}
|
Просто котельная плита CSS для макетов и типографики. У нас есть куча классов внизу для каждого индивидуального рейтинга силы. Мы добавим их к элементам при необходимости.
Реализация JavaScript
Теперь, когда у нас есть надежная структура и некоторые базовые стили, мы можем приступить к написанию необходимой функциональности. Обратите внимание, что мы широко используем jQuery. При необходимости сделайте ссылку на CDN Google.
Переменные и обработка событий
Поскольку будет продолжаться большое количество операций с числами, нам понадобится множество переменных для хранения значений. Поскольку это демонстрационный, а не производственный код, я решил объявить переменные глобальными и обращаться к ним через вспомогательные методы, а не объявлять их внутренне, а затем передавать их функциям.
var strPassword; var charPassword; var сложно = $ ("# сложность"); var minPasswordLength = 8; var baseScore = 0, оценка = 0; var num = {}; num.Excess = 0; num.Upper = 0; num.Numbers = 0; num.Symbols = 0; var bonus = {}; bonus.Excess = 3; bonus.Upper = 4; бонусные номера = 5; bonus.Symbols = 5; bonus.Combo = 0; bonus.FlatLower = 0; bonus.FlatNumber = 0;
Имена переменных довольно стандартные, но я бы все равно дал краткое изложение. strPassword содержит значение поля ввода, charPassword — это массив, содержащий каждый символ строки, сложность содержит ссылку на элемент div. Мы также определяем минимальную длину пароля, оценку и базовую оценку.
Мы создаем быстрый хеш для хранения количества дополнительных символов, символов верхнего регистра, цифр и символов. Мы делаем то же самое для бонусов. Числовой хеш содержит количество символов, а бонусный хэш содержит бонусные множители. Вы можете просто создать отдельные переменные, но я думаю, что это выглядит чище.
Не забудьте подключить обработчик события к событию.
$ ("# inputPassword"). bind ("keyup", checkVal);
checkVal — это обработчик событий, который мы создадим совсем чуть-чуть.
Обработчик событий
функция checkVal () { if (charPassword.length> = minPasswordLength) { baseScore = 50; analyzeString (); calcComplexity (); } еще { baseScore = 0; } outputResult (); }
Сначала мы проверяем длину входной строки. Если она больше или равна минимальной указанной длине, мы можем продолжить. Мы устанавливаем базовую оценку 50 и вызываем вспомогательные методы, которые занимаются анализом строки и вычислением ее сложности.
Если она меньше ожидаемой длины, мы просто устанавливаем базовый счет на 0.
Затем мы вызываем функцию outputResult, которая заботится о смысле вычисляемых вычислений. Ниже мы увидим, как это работает.
Анализ входных данных
функция analysisString () { для (i = 0; i <charPassword.length; i ++) { if (charPassword [i] .match (/ [AZ] / g)) {num.Upper ++;} if (charPassword [i] .match (/ [0-9] / g)) {num.Numbers ++;} if (charPassword [i] .match (/(.*[!,@,#,$,%,^,&,*,?,_, ~]) /)) {num.Symbols ++;} } num.Excess = charPassword.length - minPasswordLength; if (num.Upper && num.Numbers && num.Symbols) { bonus.Combo = 25; } иначе if ((num.Upper && num.Numbers) || (num.Upper && num.Symbols) || (num.Numbers && num.Symbols)) { bonus.Combo = 15; } if (strPassword.match (/ ^ [\ sa-z] + $ /)) { bonus.FlatLower = -15; } if (strPassword.match (/ ^ [\ s0-9] + $ /)) { bonus.FlatNumber = -35; } }
Это может показаться немного сложным, но я обещаю вам, это только из-за регулярных выражений. Давайте рассмотрим код по частям.
Во-первых, нам нужно выяснить состав рассматриваемой строки. Например, нам нужно выяснить, содержит ли строка буквы в верхнем регистре, цифры или символы и, если да, то сколько их присутствует. Имея это в виду, мы перебираем массив символов и проверяем каждый символ, чтобы увидеть его тип. Метод match позволяет сопоставить строку с регулярным выражением. Если вы новичок в регулярных выражениях, я предлагаю вам прочитать замечательную статью Василия здесь .
Далее мы должны определить разницу между длиной входной строки и указанной минимальной длиной пароля. Это дает нам избыточное количество персонажей для игры.
Затем мы проверяем, имеет ли строка верхний регистр, цифры и символы. Если так, предоставьте бонус. Мы также проверяем, есть ли у них комбинации из двух из них, и в этом случае предоставляем меньший бонус.
Наконец, мы проверяем, является ли строка плоской: содержит ли она только строчные буквы или только цифры. Мы проверяем это с помощью регулярного выражения и, если это так, оштрафуем пароль для этой практики.
Рассчитать сложность
функция calcComplexity () { счет = baseScore + (num.Excess * bonus.Excess) + (num.Upper * bonus.Upper) + (num.Numbers * bonus.Numbers) + (num.Symbols * bonus.Symbols) + bonus.Combo + bonus.FlatLower + bonus.FlatNumber; }
Просто простое дополнение. Мы добавляем базовую оценку к произведению количества лишних символов и его множителя. То же самое для заглавных букв, цифр и символов. Затем мы добавляем бонус за комбинации, если они есть, и добавляем штрафы, если строка плоская.
Обновление интерфейса
Теперь, когда все вычисления позади, мы можем обновить пользовательский интерфейс, чтобы отразить изменения. Вот каждое из государств.
функция outputResult () { if ($ ("# inputPassword"). val () == "") { сложность.html («Введите случайное значение»). addClass («по умолчанию»); } еще если (charPassword.length <minPasswordLength) { сложность.html («По крайней мере» + minPasswordLength + «символы, пожалуйста!»). addClass («слабый»); } еще если (оценка <50) { complexity.html ( "Слабое!") addClass ( "слабый"). } иначе если (оценка> = 50 && оценка <75) { complexity.html ( "Среднее!") addClass ( "сильный"). } иначе если (оценка> = 75 && оценка <100) { complexity.html ( "Strong!") addClass ( "сильнее"). } иначе если (оценка> = 100) { complexity.html ( "Безопасно!") addClass ( "сильный"). } }
Ничего необычного здесь, но мы будем проходить это построчно.
Сначала мы проверим, является ли ввод пустым. Если это так, измените текст результата и добавьте класс по умолчанию, чтобы изменить его цвет фона на его первоначальный серый.
Если она меньше указанной минимальной длины, мы соответствующим образом изменим текст и добавим слабый класс, чтобы его фон был красным. Мы делаем то же самое, если общий балл меньше 50, но меняем текст на слабый .
По мере увеличения оценки мы соответственно меняем текст и добавляем необходимые классы. Не стесняйтесь изменять базовые оценки для каждого рейтинга. Я просто ввел ненаучные ценности, чтобы запустить демо.
Обновление подробной разбивки
Теперь, когда основной результат обновлен, мы можем посмотреть на обновление статистики.
функция outputResult () { // Предыдущий код $ ("# details"). html ("Базовая оценка: <span class = \" value \ ">" + baseScore + "</ span>" + "<br /> Длина бонуса: <span class = \" value \ ">" + (num.Excess * bonus.Excess) + "[" + num.Excess + "x" + bonus.Excess + "] </ span > " + "<br /> Бонус в верхнем регистре: <span class = \" value \ ">" + (num.Upper * bonus.Upper) + "[" + num.Upper + "x" + bonus.Upper + "] </ span> " + "<br /> Номер Бонус: <span class = \" value \ ">" + (num.Numbers * bonus.Numbers) + "[" + num.Numbers + "x" + bonus.Numbers + "] </ span >» + "<br /> Symbol Bonus: <span class = \" value \ ">" + (num.Symbols * bonus.Symbols) + "[" + num.Symbols + "x" + bonus.Symbols + "] </ span >» + "<br /> Комбинированный бонус: <span class = \" value \ ">" + bonus.Combo + "</ span>" + "<br /> Только строчные буквы: <span class = \" value \ ">" + bonus.FlatLower + "</ span>" + "<br /> Штраф только за номера: <span class = \" value \ ">" + bonus.FlatNumber + "</ span>" + "<br /> Общая оценка: <span class = \" value \ ">" + оценка + "</ span>" }
Эта часть не так запутана, как кажется. Позволь мне объяснить.
Вместо того, чтобы просто обновлять отдельные значения для подробных результатов, я прибегнул к обновлению полного значения HTML контейнера. Я знаю, что это будет вялым, когда количество этих блоков сложится, но доступ к каждому элементу индивидуально и последующее обновление его значения для крошечной демонстрации показалось довольно контрпродуктивным. Так что беги со мной здесь.
Это похоже на введение обычного HTML в элемент, за исключением того, что мы поместили пару переменных внутрь, чтобы детали могли быть обновлены мгновенно. Каждое значение получает класс значения, чтобы сделать его жирным. Мы также отображаем количество специальных символов и их множитель, чтобы пользователь мог определить, какие элементы получают больший вес.
Несколько твиков
На данный момент, есть 2 ошибки, которые обнаруживаются.
- Если вы введете длинный пароль и затем удалите текстовое поле, цвета фона не изменятся.
- В этом же сценарии детали точек не обновляются должным образом.
Мы будем решать их один за другим.
Для первой ошибки основной причиной является то, что мы не удаляем все остальные классы. Это не будет проблемой, если последние добавленные классы будут иметь приоритет над другими. К сожалению, это не так. Вот быстрое решение.
функция outputResult () { if ($ ("# inputPassword"). val () == "") {сложность.html («Введите случайное значение»). removeClass («слабый сильный сильный сильный»). addClass («по умолчанию»);} еще если (charPassword.length <minPasswordLength) {сложность.html ("По крайней мере" + minPasswordLength + "символы, пожалуйста!"). removeClass ("сильный сильнее сильного"). addClass ("слабый");} еще если (оценка <50) {сложность.html ("Слабый!"). removeClass ("сильный, сильный, самый сильный"). addClass ("слабый");} иначе если (оценка> = 50 && оценка <75) {сложность.html ("Средний!"). RemoveClass ("сильный сильнейший"). addClass ("сильный");} иначе если (оценка> = 75 && оценка <100) {Complexity.html ( "Strong!") RemoveClass ( "сильный") addClass ( "сильнее");..} иначе если (оценка> = 100) {Complexity.html ( "Безопасно!") AddClass ( "сильный");.} // Подробности обновления кода }
Вы, вероятно, спрашиваете, почему мы не удаляем каждый класс здесь. Ответ прост: мы используем один из основных атрибутов CSS: каскадирование . Если вы обратите внимание на порядок объявления каждого класса в файле CSS, вы заметите, что default происходит первым, а самый сильный — последним, что означает, что если элемент имеет самый сильный класс, он будет переопределять любые изменения, сделанные любым классом над ним. Таким образом, мы должны удалить только те классы, которые находятся ниже соответствующего класса. Например, чтобы элемент имел сильный , нам нужно удалить более сильный и сильный классы.
Вторая ошибка существует из-за того, что индивидуальные переменные не сбрасываются при возникновении нового события. Они переносятся и на следующее событие. Чтобы это исправить, мы создаем быструю функцию, которая повторно инициализирует все соответствующие переменные и добавляем в нее обработчик события checkVal, чтобы он вызывался каждый раз, когда обновляется текст поля ввода.
функция 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; оценка = 0; }
функция checkVal () { в этом(); // Другой код }
Ограничения
Если вы немного поигрались с демо, вы заметите, что Pa $$ W0rd $ становится безопасным паролем, хотя на самом деле он скоро будет взломан. Это связано с простотой нашего алгоритма здесь. Мы не проверяем замены персонажей. Или общие пароли или шаблоны в этом отношении. Выполнение таких вещей увеличило бы сложность этого урока, уменьшив его доступность, и то, и другое я не хотел для этой конкретной статьи.
Это предназначено в качестве основной проверки надежности пароля. Если вам нужно его усилить, вы можете добавить еще пару регулярных выражений для проверки шаблонов и повторения символов, а затем соответствующим образом настроить результаты.
Поиск входных данных по словарю на самом деле выходит за рамки этой статьи и потребует либо огромного словаря, загруженного на клиентскую сторону, либо подключения его к системе на стороне сервера, чтобы сделать это. Снова, я действительно хотел избежать их обоих на этот раз.
Вывод
И вот что у вас есть: как добавить удобную для пользователя функциональность, возможность сообщить пользователю силу пароля, который он только что ввел, в ваши проекты. Надеюсь, вы нашли этот урок интересным, и он был вам полезен. Не стесняйтесь многократно использовать этот код в других местах своих проектов и звоните сюда, если у вас возникнут трудности.
Вопросов? Хорошие вещи, чтобы сказать? Критицизмы? Нажмите на раздел комментариев и оставьте мне комментарий. Удачного кодирования!
- Подпишитесь на нас в Твиттере или подпишитесь на ленту Nettuts + RSS для получения лучших учебных материалов по веб-разработке.