Индикатор пароля должен помогать, а не обещать безопасность по одной зелёной полоске. Вы оцените длину и разнообразие, подсветите конкретные улучшения, добавите кнопку показа и оставите финальную проверку серверу.
Правило «одна заглавная, одна цифра, один символ» легко превращается в предсказуемый пароль. Для учебного индикатора мы дадим длине самый большой вес, отдельно отметим разнообразие и предупредим о частых шаблонах. Это подсказка, а не криптографическая экспертиза.
Длина даёт основной вклад, классы символов добавляют баллы.
Пользователь видит не запрет, а следующий полезный шаг.
Backend всё равно проверяет правила и хранит только стойкий хеш.
Какие признаки можно проверить в браузере
Функция evaluate принимает строку и возвращает score, label и массив hints. Интерфейс только отображает результат. Кнопка показа меняет type между password и text и обновляет aria-pressed. Вставку не блокируем: менеджеры паролей должны работать.
| Признак | Баллы | Комментарий |
|---|---|---|
| 12+ символов | 2 | Длина важнее замены букв на знаки |
| 16+ символов | ещё 1 | Длинная фраза заметно лучше |
| Разные регистры | 1 | Дополнительное разнообразие |
| Цифра и символ | 1 | Не должны быть единственным правилом |
После этого шага у каждой части есть одна роль. Интерфейс собирает действие, логика меняет состояние, а вывод показывает признак успеха. Это проще отлаживать, чем один большой обработчик.

Пароль не покидает компонент. На сервер уходит только отправленная форма по HTTPS
Пишем оценку и живую шкалу
Эта функция намеренно проста и объяснима. Она снижает оценку для нескольких очевидных шаблонов, но не знает утечки и словари всех языков. Для серьёзного продукта используйте проверенный оценщик и серверную политику.
function evaluate(password){
let score=0;
const hints=[];
if(password.length>=12) score+=2; else hints.push('Используйте не меньше 12 символов');
if(password.length>=16) score+=1;
if(/[a-zа-я]/.test(password)&&/[A-ZА-Я]/.test(password)) score+=1;
else hints.push('Добавьте буквы разного регистра');
if(/\d/.test(password)&&/[^\p{L}\d]/u.test(password)) score+=1;
else hints.push('Добавьте цифру и специальный символ');
if(/password|qwerty|12345|пароль/i.test(password)){score=Math.min(score,1);hints.unshift('Не используйте распространённый шаблон')}
const labels=['Очень слабый','Слабый','Средний','Хороший','Сильный','Сильный'];
return {score,label:labels[score],hints};
}
const input=document.querySelector('#password');
const meter=document.querySelector('#strength');
const note=document.querySelector('#hint');
input.addEventListener('input',()=>{
const result=evaluate(input.value);
meter.value=result.score; meter.textContent=result.score + ' из 5';
note.textContent=input.value?(result.label + '. ' + (result.hints[0]??'Хорошая длина и разнообразие.')):'Введите пароль';
});
document.querySelector('#reveal').addEventListener('click',event=>{
const visible=input.type==='text'; input.type=visible?'password':'text';
event.currentTarget.setAttribute('aria-pressed',String(!visible));
event.currentTarget.textContent=visible?'Показать':'Скрыть';
});Оценка отделена от DOM и легко тестируется. Длина весит больше декоративной сложности. Подсказка называет одно конкретное улучшение. Кнопка показа доступна с клавиатуры и не ломает вставку.

Помощь лучше механического запрета. Сравнение показывает, какой вариант легче поддерживать и проверять.
Почему зелёная полоска не гарантирует безопасность
Frontend-проверка видна пользователю и может быть обойдена прямым запросом. Сервер обязан повторить минимальные правила. Сам пароль нельзя логировать или хранить как обычную строку: сервер сохраняет результат специализированного медленного хеширования с солью.
| Что делает компонент | Что он не делает |
|---|---|
| Показывает понятные подсказки | Не проверяет все известные утечки |
| Помогает выбрать длину | Не заменяет серверную валидацию |
| Разрешает менеджер паролей | Не хранит пароль |
| Показывает или скрывает ввод | Не отправляет значение сам |
Сохраняйте в одном месте то, что может измениться. Если одно и то же значение скопировано в три функции, после первой правки они начнут расходиться. Один объект состояния и одна функция отрисовки снимают эту проблему.
Практика: проверяем ввод и доступность
Проверьте пустую строку, 12 одинаковых букв, длинную фразу, qwerty12345 и вставку из менеджера паролей. Переключите видимость клавиатурой. Убедитесь, что пароль нигде не появляется в console.log, URL или тексте ошибки.
- Введите короткий пароль из букв.
- Доведите длину до 12 символов.
- Проверьте qwerty12345 и слово «пароль».
- Вставьте длинную парольную фразу.
- Переключите видимость через Tab и Enter.
- Отправьте форму и повторите минимальную проверку на сервере.
Подсказка меняется на каждом input. Шкала имеет текстовую альтернативу. Вставка работает. Пароль не попадает в логи, URL и localStorage.

Компонент касается безопасности и доступности. Пройдите все четыре сценария перед публикацией проекта.
Доводим поле пароля до готового компонента
Следующий шаг для настоящей формы: автозаполнение current-password или new-password, серверная проверка и корректное сообщение об ошибке. Не заставляйте пользователя менять пароль по расписанию без причины и не запрещайте пробелы или вставку.
Ломаются менеджеры паролей и длинные значения.
Цвет не объясняет результат и недоступен части пользователей.
Её можно обойти прямым запросом.
Секрет остаётся доступным скриптам страницы.
Что получится в итоге

Готовое поле показывает понятную шкалу, одну полезную подсказку и кнопку просмотра, не мешая вставке из менеджера паролей.
Что важнее для простой оценки?
Достаточная длина, а не обязательная замена каждой буквы специальным знаком.
Где повторяются правила?
На сервере, потому что frontend можно обойти.
Можно ли запрещать вставку?
Нет, это мешает менеджерам паролей и длинным уникальным паролям.
Как понять, что проект готов?
Он повторяет целевой сценарий несколько раз подряд, понятно реагирует на ошибочный ввод и не теряет состояние при обычных действиях.
Можно ли копировать код целиком?
Можно как стартовую точку, но сначала замените значения из примера, затем запустите проект по шагам. Если вы не можете объяснить одну строку, её лучше разобрать до следующего шага.
Строки, регулярные выражения и события разбираются в курсе JavaScript. Форму можно соединить с Fetch API только после серверной валидации.
Если обработчик не видит поле, проверьте ошибку null, а визуальный режим дополните тёмной темой. В Кодике удобно прогнать набор тестовых строк без реальных паролей.