Desenvolvendo Aplicação de Medidor de Senhas Fortes e Seguras com AngularJs
Mais uma vez….. olá a todos! Conforme prometido, estou aqui novamente escrevendo mais um artigo e tutorial em como desenvolver uma aplicação utilizando uma biblioteca do JavaScript — zxcvbn — para criar um medidor de senha forte e segura em AngularJs.
Vamos prosseguir e claro dar as boas vindas a todos!! 😀
Nesse tutorial, estaremos criando um formulário de registro simples com campos: nome completo, email e senha. Para esse tutorial estaremos utilizando a biblioteca zxcvbn.
O objetivo dessa biblioteca do JavaScript é justamente estimar e mostrar para o usuário que está realizando o cadastro em um determinado formulário se a senha que ele está criando é segura e forte. A aplicação que vamos desenvolver será possível fornecer ao usuário um feedback visual. Também usaremos o AngularJs para realizar as ligações via two-way data binding na aplicação a ser desenvolvida.
Mas… Por que devemos medir as senhas criadas??? 😐
Senhas são atualmente uma das coisas mais comuns que necessitamos para criar uma determinada autenticação do usuário na maioria das aplicações da web nos nossos dias. E como por conta disso, se faz necessário que as senhas criadas pelos usuários sejam bastante seguras e fortes.
Ao longo dos anos, técnicas como Função Hash Criptográfica — que envolve uma criptografia do tipo Sal que tem como objetivo, na maioria das vezes, para empregar e ocultar a representação real de senhas que serão armazenadas na base de dados.
Embora a senha criada por meio de hash seja uma senha que dá proteção da senha, o usuário ainda representa um grande desafio para a segurança de senhas. Que, por mais que exista toda uma grande segurança no desenvolvimento da senha por meio de senhas criptografadas, se um determinado usuário escolhe uma senha que seja fácil de ser descoberta, poderá causar um grande risco de ser atacado.
Mas, como? Um usuário que usa uma palavra muito comum como senha, poderá tornar o esforço de hash inútil, uma vez que o hacker se fizer uso de um ataque de força bruta poderá hackear essa senha em pouco tempo. E para piorar a situação, se o hacker fazer uso de uma infra-estrutura altamente sofisticada para realizar esse ataque, poderá levar milissegundos, dependendo da complexidade ou comprimento da senha.
Muitas aplicações web hoje, como por exemplo: Google, Twitter, Dropbox, Facebook entre outros, procuram orientar os usuários a criarem senhas consideravelmente forte, justamente para poder garantir um determinado comprimento mínimo de senha ou alguma combinação de caracteres alfanuméricos e ou até mesmo utilização de caracteres ou símbolos na senha.
Mas, vem a pergunta… como é realizado um medidor de senha forte? Para garantir a total segurança de seus usuários, os desenvolvedores do Dropbox desenvolveram um algoritmo par estimar uma senha forte. Este algoritmo está num pacote da biblioteca do JavaScript chamado zxcvbn. Além disso, o pacote contém um dicionário de palavras, nomes e senhas em inglês mais usadas.
Vamos começar?!!! 😀
Antes de começarmos esse tutorial gostaria de deixar claro alguns fatores importantes para o prosseguimento do desenvolvimento da aplicação.
Precisa ter conhecimentos prévios em AngularJs. Caso não tenha, o próprio site do AngularJs fornece um tutorial totalmente step-by-step ensinando como desenvolver uma pequena aplicação com o framework. Estarei fornecendo aqui agora alguns sites muito importantes que te auxiliará a aprender a desenvolver aplicações em AngularJs
Lembrando que se faz necessário ter conhecimentos básicos sobre JavaScript… Caso não tenha, eu super recomendo o curso de JavaScript do Rodrigo Branas — Desvendado a Linguagem JavaScript 😀
obs.: Nesse tutorial estarei utilizando o AngularJs versão 1.x. Sei que já tem a versão 2… mas como é uma versão recente e pouco conhecida por alguns.. vou estar utilizando a versão 1.x
Se faz necessário o download de todas as dependências que iremos precisar. E uma delas que vamos utilizar é o pacote Bower. Se você ainda não tiver o Bower no seu computador, siga as instruções do Guia de Instalação do Bower — AQUI. E execute o seguinte comando para instalar todas as dependências para o tutorial:
> bower install zxcvbn angularjs#1.5.9 bootstrap
Lembrando que, para realizar o download do pacote acima, se faz necessário fazer download do Node.Js! 😉
Esse pacote já irá baixar: bootstrap, jquery, zxcvbn e o angularJs. Então…
A estrutura da aplicação será bem simples, não quero deixar esse projeto muito extensivo… com isso, irá conter duas pastas e um arquivo:
- Pasta: assets
- Pasta: bower_components
- Arquivo: index.html
A estrutura do nosso projeto deverá ficar como segue a imagem abaixo:
Antes de começarmos…. peço que façam o seguinte: vão até a pasta bower_components -> angularJs -> package.json. Abaixo do scripts adicione seguinte código:
(abaixo de script)(...)"postinstall": "bower install","prestart": "npm install",
"start": "http-server -a localhost -p 8000 -c-1 ./app","pretest": "npm install",
"test": "karma start karma.conf.js",
"test-single-run": "karma start karma.conf.js --single-run","preupdate-webdriver": "npm install",
"update-webdriver": "webdriver-manager update","preprotractor": "npm run update-webdriver",
"protractor": "protractor e2e-tests/protractor.conf.js"(...)
Caso não consigam compreender onde e como… estou disponibilizando o código desse tutorial no meu repositório do GitHub — AQUI
Bom… feito isso, estamos prontos para começar a desenvolver a nossa aplicação. 😀
Começando com o HTML
Bom, vamos começar adicionando marcação básica para a nossa página no arquivo index.html. E também vamos aproveitar para poder fazer o link dos arquivos de bootstrap. Que nesse caso é:
- bootstrap.min.css
- bootstrap-theme.min.css
- angular.min.js
E também, vamos incluir os arquivos css e js no nosso projeto na pasta assets. Vejamos como vai ficar as primeiras linhas de código:
Muitas linhas de código até aqui não é mesmo?! Peço que vocês adicionem os arquivos: .bower.json e package.json na raiz principal do projeto. Pois esses dois arquivos nos ajudarão quando formos executar o projeto via npm para abrir a aplicação via localhost, assim como segue a imagem abaixo:
Agora abre o cmd da sua máquina e vai até a pasta do projeto e digite o comando: npm start, depois digite localhost:8000/index.html e voilá! Vejam o resultado abaixo:
HTML e CSS simples…. por enquanto…. mas chegando ao final do projeto vamos fazer um ajustes para melhorar o visual dessa página 😉
Agora vamos carregar de maneira assíncrona o pacote zxcvbn em nossa página. Para isso, devemos adicionar o script na pasta: assets/js/app.js. O script a seguir criará um novo elemento <script> que é inserido antes do primeiro elemento script definido na página quando o carregamento é terminado. O src dele elemento script apontará para o arquivo zxcvbn.js. O atributo async também será definido como true para permitir o carregamento assíncrono.
Adicione o código abaixo no arquivo: app.js
(function() {
var ZXCVBN_SRC = 'bower_components/zxcvbn/dist/zxcvbn.js';
var async_load = function() {
var primeiroElemento, scrt;
/* Criando um elemento para ser usado pelo DOM API*/
scrt = document.createElement('script');
/* Iniciar os atributos no elemento script */
scrt.src = ZXCVBN_SRC;
scrt.type = 'text/javascript';
scrt.async = true; //async é um atributo do HTML5
/* Agora aqui nós vamos pegar o primeiro elemento do script no documento */
primeiroElemento = document.getElementsByTagName('script')[0];
/* Em seguida vamos inserir o elemento antes do primeiro elemento no documento */
return primeiroElemento.parentNode.insertBefore(scrt, primeiroElemento);
};
/* Agora... vamos adicionar o async_load como callback para o evento window load */
if (window.attachEvent != null) {
window.attachEvent('onload', async_load);
} else {
window.addEventListener('load', async_load, false);
}
}).call(this);
Agora vamos testar a função zxcvbn() com qualquer string que simule uma senha no console do nosso navegador. A função zxcvbn() retorna um Object com inúmeras propriedades. Porém neste tutorial, estaremos mais focados na propriedade score, que é um propriedade do tipo inteiro de 0 a 4 (muito útil para implementar uma barra de senha segura).
- 0 — senha extremamente fácil
- 1 — senha muito fácil
- 2 — senha fácil
- 3 — senha pouco forte
- 4 — senha extremamente forte
Agora vamos executar e testar essa função no console do nosso navegador simulando uma senha muito fácil e outra muito forte. Observem a propriedade score …. e vejam o resultado:
Show de bola não é mesmo?! Isso é um sintoma de que a função que implementamos no arquivo app.js está funcionando. Agora vamos implementar em nosso projeto o AngularJs! 😉
Usando Elementos do AngularJs no Projeto
Vamos agora fazer algumas melhorias no nosso código usando o AngularJs. Primeiro vamos criar um módulo para o nosso aplicativo e vamos chamar de: SenhaSegura, e um controlador simples para o nosso formulário chamado: FormController. Então para isso, vão até o arquivo: app.js e adicione abaixo do código já criado e acrescente essas duas linhas de código:
(...)/* Criando um módulo da aplicação */angular.module('senhaSegura', []);/* Aqui estamos adicionando o controle do módulo criado */angular.module('senhaSegura').controller('FormController',function($scope) {});
A próxima coisa a fazer é alterar algumas partes do arquivo index.html para adicionarmos uma diretiva ng-app para o módulo no elemento <html> e uma diretiva ng-controller para o controlador no elemento <form>
Validando o Formulário
Agora que já adicionamos o AngularJs no projeto, vamos trabalhar com a questão do desenvolvimento da lógica da validação do formulário.Para isso, vamos seguir os passos abaixo:
- Vamos nomear os campos do nosso formulário. E também, adicionaremos as diretivas ng-model nos campos de entrada para que possamos usar o NgModelController.
- Em seguida, adicionamos a diretiva ng-required nos campos de entrada, uma vez que desejamos que os campos devem ser preenchidos.
- Vamos também desabilitar o botão Enviar usando a diretiva ng-disabled e somente habilitar quando o formulário estiver totalmente preenchido e validado.
- E finalmente, vamos aproveitar as diretivas ng-class e ng-show para fornecer uma mensagem de retorno para os elementos de entrada.
O código do formulário modificado no arquivo index.html deverá estar de acordo com o código abaixo:
Vamos entender o que fizemos até agora aqui. No código acima, nomeamos o nosso formulário como cadastreAqui e damos os nomes aos elementos de entrada, tornando possível para aproveitar o NgModelController interno do AngularJs. Também criamos data-bindings para os elementos de entrada usando a diretiva ng-model.
Usamos algumas propriedades de estado para fins de validação: -$dirty, $invalid, $error que já são fornecidas pela API NgModelController (mais informações AQUI) para determinar se o nosso formulário está totalmente validado. A diretiva ng-class é usada para adicionar dinamicamente uma classe de erro aos elementos de entrada com base nos critérios de validação.
E também, usamos a diretiva ng-cloak para impedir que o navegador mostre as mensagens de erro durante a renderização. Uma vez que, incluímos em nosso projeto o Angular.Js no final da nossa página, isso não seria eficaz. Para corrigir isso, adicionaremos a seguinte regra CSS ao arquivo style.css:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
Depois de realizar tais mudanças… o nosso formulário deve estar de acordo com a imagem abaixo:
Observem que o botão Enviar está desabilitado! Isso é um bom sinal de que as validações que desenvolvemos em AngularJs estão funcionando. Mas, vamos prosseguir que tem mais alguns detalhes para incluir em nosso projeto. 😀
Adicionando o Medidor de Força da Senha 😀
Agora…. vamos desenvolver a parte mais interessante em nosso projeto e o ponto focal desse tutorial: o medidor de força de senha. Para isso, vamos criar uma nova diretiva para o nosso módulo senhaOk, que irá definir uma restrição de validação personalizada para o elemento password. Isso ajudará a garantir que uma senha válida deverá conter mais de 7 caracteres e deve ter uma pontuação mínima na função zxcvbn() de 2. Iremos também adicionar uma mensagem de retorno para o usuário para acompanhar o comprimento da senha criada.
Primeiramente, vamos adicionar no arquivo index.html, após o elemento password, a lógica para medir a força da senha a ser criada.
Aqui estamos usando a classe ng-class e as classes do Bootstrap para fornecer uma mensagem de retorno com base no comprimento da senha. Também estamos usando um filtro de senha personalizado para formatar a exibição do comprimento da senha, que nesse caso terá um comprimento acima de 7 caracteres.
Realizando todas as modificações acima, o nosso projeto deve parecer como a imagem abaixo. Observe que há um comportamento estranho em nosso projeto… mas iremos resolver isso, uma vez que formos tratar o filtro tamanhoSenha
Antes de prosseguir, vamos definir o filtro para o tamanhoSenha que irá formatar a exibição do comprimento da senha na visualização para o usuário. Vamos acrescentar o seguinte código no arquivo app.js para criarmos o filtro:
angular.module('SenhaSegura', []); /* Aqui estamos adicionando o controle do módulo criado */ angular.module('SenhaSegura').controller('FormController',function($scope) {}); /** Criando um filtro para tamanhoSenha */ angular.module('SenhaSegura').filter('tamanhoSenha', [function() { return function(valor, maximo) { var valor = angular.isString(valor) ? valor : '', maximo = isFinite(maximo) ? maximo : 7; return valor &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; (valor.length &amp;amp;amp;amp;gt; maximo ? maximo + '+' : valor.length); }; }]);
No código acima, o filtro tamanhoSenha receberá um valor de uma cadeia de string e um parâmetro de valor maximo opcional que assume como padrão o valor 7. Se o comprimento da sequencia de entrada for menor que o valor máximo, ele retornará o comprimento da sequencia de caracteres. Caso contrário, ele retornará um valor {maximo}+
Observem a mensagem de erro visual para o comprimento da senha:
Bom, agora vamos continuar a criar uma diretiva chamada senhaOk para o campo senha. Vamos também criar um serviço que irá encapsular a implementação da função zxcvbn(). Vamos adicionar o código a seguir no arquivo app.js para criar o serviço:
/* Criando aqui um serviço para a funcionalidade zxcvbn() */ angular.module('SenhaSegura').factory('zxcvbn', [function(){ return { score: function() { var count = zxcvbn.apply(null, arguments); return count &amp;amp;amp;&amp;amp;amp; count.score; } }; }]);
Aqui criamos um serviço chamado zxcvbn que fornecerá uma pontuação provido da API do método score. O score() utilizará os mesmos parâmetros que a função zxcvbn() e o chamará internamente. Com isso, irá retornar uma pontuação estimada da senha forte que o usuário está criando.
Agora, podemos aplicar esse serviço para criar a nossa diretiva. Adicionar o seguinte código no arquivo app.js:
/* Criando aqui uma diretiva para o 'senhaOk' como dependência do 'zxcvbn' */ angular.module('SenhaSegura').directive('senhaOk', ['zxcvbn', function(zxcvbn) { return { restrict: 'AC', required: 'ngModel', link: function($scope, $element, $attrs, $ngModelCtrl) { $element.on('blur change keydown', function(e) { $scope.$evalAsync(function($scope) { var senha = $scope.senha = $element.val(); $scope.senhaSegura = senha ? (senha.length &amp;amp;amp;&amp;amp;amp; 7 &amp;amp;amp;&amp;amp;amp; zxcvbn.score(senha) || 0) : null; ngModelCtrl.$setValidity('senhaOk', $scope.senhaSegura &amp;amp;amp;amp;gt;= 2); }); }); } }; }]);
Aqui definimos a diretiva senhaOk com o serviço zxcvbn como uma dependência. Especificamos que a diretiva pode ser usada como uma classe ou como um atributo. Também especificamos que precisamos do NgModelController.
Na função link(), adicionamos um evento no elemento que será acionado nos eventos de desfocagem, alteração e keyup. O ouvinte de eventos usa o método $scope.$evalAsync() para atrasar a atualização das propriedades do escopo. Além disso, o método $setValidity() do NgModelController foi usado para definir o critério de validade para a restrição de validação senhaOk.
E finalmente adicionaremos o senha-ok como atributo ou classe no elemento password para que seja aplicada a validação da diretiva criada.
<input type="password" class="form-control senha-ok" ng-class="(cadastreAqui.senha.$dirty &amp;amp;amp;&amp;amp;amp; cadastreAqui.senha.$invalid) ? 'error' : ''" id="senha" name="senha" placeholder="Digite a Senha" ng-required="true" ng-model="senha"&amp;amp;gt;
Vejam o resultado final do nosso projeto desenvolvido! 😀 😀 😀
Notem que a barra que mede a força da senha está funcionando de maneira correta. Ou seja, está tudo funcionando corretamente! ❤ ❤ ❤
Agora observem como o botão “Enviar” ficará habilitado uma vez que preenchemos todos os campos. (fiz algumas alterações no html para deixar o projeto mais apresentável!! :D)
Ficou bem mais lindo não é mesmo!!! ❤❤❤
O código final da nossa página do index.html AQUI
Palavras Finais
Nesse tutorial, aprendemos como implementar um medidor de força para senha com base na biblioteca JavaScript: zxcvbn em nossa aplicação AngularJs. Caso queira se aprofundar mais nessa biblioteca, há um guia detalhado com documentação no repositório do GitHub do zxcvbn AQUI .
Os códigos desenvolvidos estão no meu repositório do GitHub: AQUI.
E caso desejam ver a DEMO desse projeto encontra-se AQUI.
Agradeço mais uma vez a todos e espero que tenham gostado! Até a próxima! 😀
Originally published at code4coders.wordpress.com on January 23, 2017.