Criando um validador de senha em JavaScript
Como montar um medidor de força de senha com HTML, CSS e JavaScript puro, validando maiúsculas, minúsculas, números, caracteres especiais e tamanho mínimo com expressões regulares.
Validar senha parece complicado até você abrir o código e ver que é basicamente uma lista de regras sendo checadas uma por uma. Aqui a base é um HTML e um CSS simples, só para dar suporte visual, e o JavaScript inteiro construído do zero, regra por regra, até chegar numa barra de progresso que mostra o quanto da senha já está válida.
O que o validador precisa fazer
O objetivo final: conforme o usuário digita, quatro regras vão sendo marcadas como cumpridas ou não, e uma barra de progresso preenche proporcionalmente. Quando as quatro regras estão satisfeitas, a senha é considerada válida e dá para liberar o que vier depois, enviar o formulário, habilitar um botão, o que fizer sentido pro seu caso.
As quatro regras:
- Pelo menos uma letra maiúscula e uma minúscula.
- Pelo menos um número.
- Pelo menos um caractere especial.
- Pelo menos seis caracteres no total.
Selecionando os elementos
Primeiro, o campo de senha e a barra de progresso, os dois elementos que o JavaScript vai manipular o tempo todo:
const passwordInput = document.querySelector(".password");
const progressBar = document.querySelector(".progress .bar");E o gatilho de tudo: sempre que o usuário soltar uma tecla dentro do campo, a validação roda de novo:
passwordInput.addEventListener("keyup", checkPassword);Calculando a força regra por regra
Dentro de checkPassword, a lógica começa com a força zerada e vai somando um ponto para cada regra satisfeita:
function checkPassword() {
let strength = 0;
const value = passwordInput.value;
strength += renderRule(".lower-upper-case", value.match(/[a-z].*[A-Z]|[A-Z].*[a-z]/));
strength += renderRule(".one-number", value.match(/[0-9]/));
strength += renderRule(".one-special-char", value.match(/[!@#$%^&*_]/));
strength += renderRule(".min-char", value.length >= 6);
const pct = Math.floor((strength / 4) * 100);
progressBar.style.width = `${pct}%`;
// liberar envio, mostrar botão, etc, quando pct === 100
}A primeira regra usa duas expressões regulares unidas por | (ou), uma checando minúscula seguida de maiúscula em qualquer ordem e outra checando o inverso, porque não importa qual vem primeiro, só importa que as duas apareçam. As outras duas regras usam expressões bem mais diretas: um intervalo de números de 0 a 9 e uma lista de caracteres especiais entre colchetes. A última regra nem precisa de regex, é só conferir o length da string.
A função que pinta a regra de verde ou vermelho
renderRule recebe a classe do elemento da regra e o resultado da verificação, e faz duas coisas: muda a cor da bolinha na tela e devolve 1 ou 0 para entrar na soma da força:
function renderRule(ruleClass, valid) {
const ruleArea = document.querySelector(ruleClass);
ruleArea.querySelector(".valid").style.backgroundColor = valid ? "green" : "red";
return valid ? 1 : 0;
}Cada regra no HTML tem uma classe própria (.lower-upper-case, .one-number, .one-special-char, .min-char) e, dentro dela, um elemento .valid que é a bolinha colorida. match retorna um resultado truthy quando encontra a expressão regular no texto e null quando não encontra, então dá para usar o retorno direto como o valid da função, sem precisar de um if separado para cada regra.
A barra de progresso
Com quatro regras no total, cada uma vale 25% da barra. O cálculo é simples: força dividida pelo total de regras, vezes 100, arredondado para baixo com Math.floor para garantir que só bate 100% quando as quatro regras realmente estão completas:
const pct = Math.floor((strength / 4) * 100);
progressBar.style.width = `${pct}%`;Arredondar para baixo evita que 99.9% apareça como barra cheia sem a senha estar de fato válida.
Resultado
Com isso, o campo vai ganhando cor nas regras conforme o usuário digita e a barra de progresso acompanha em tempo real. A partir do pct === 100, dá para tomar qualquer decisão: liberar um botão de envio, desbloquear o próximo passo de um cadastro, mostrar uma mensagem de sucesso. A lógica em si, checar regra por regra e somar uma força, é a parte que vale levar para qualquer linguagem ou framework, independente de como a interface é montada.
Leia também