Validando senhas fortes com Ruby on Rails e JavaScript
Leia em 2 minutos
Em muitos projetos, é importante que o usuário informe senhas que tenham um mínimo de complexidade, evitando que sejam facilmente quebradas. Existem muitas soluções feitas em JavaScript, mas não encontrei nenhuma que fosse boa o bastante no backend.
Pensando nisso, criei uma gem chamada Password Strength que faz validação de diversos padrões, a fim de identificar senhas que sejam fracas. Ela é composta por 2 módulos: ActiveRecord e JavaScript.
A validação da senha é feita com base nas seguintes regras:
- Tamanho da senha
- Presença de letras, números e caracteres especiais
- Presença de maiúsculas e minúsculas
- Uso do login/e-mail na composição da senha
- Sequências (123, abc, aaa)
- Repetições
Cada uma dessas regras recebe uma pontuação negativa ou positiva, que irá influenciar no resultado final. Assim, com base nessas regras, podemos classificar as seguintes senhas:
123=> fraca123abc=> fracaaaaaaa=> fracamyPass145=> boamyPass145$=> forte
Instalação
Para instalar, basta executar o comando
sudo gem install password_strengthAgora, configure seu aplicativo para carregá-la. No Rails 2, basta adicionar a linha abaixo ao seu arquivo environment.rb.
config.gem "password_strength"No Rails 3, adicione a linha abaixo ao arquivo Gemfile.
gem "password_strength"Se quiser usar o plugin para jQuery, você também precisará dos arquivos password_strength.js e jquery.strength.js.
Usando na prática
O Password Strength permite que você valide senhas sem a necessidade de usar o ActiveRecord.
strength = PasswordStrength.test("johndoe", "mypass")
#=> return an object
strength.good?
#=> status == :good
strength.weak?
#=> status == :weak
strength.strong?
#=> status == :strong
strength.status
#=> can be :weak, :good, :strong
strength.valid?(:strong)
#=> status == :strong
strength.valid?(:good)
#=> [:good, :strong].include?(status)Muito simples!
ActiveRecord
O Password Strength possui suporte para ActiveRecord 2.3+ (foi testado em 2.3.5 e 3.0.0-beta).
No seu modelo, adicione a validação validates_strength_of.
class User < ActiveRecord::Base
validates_strength_of :password
endPor padrão, as opções serão :level => :good, :with => :username. A opção :level define a complexidade mínima requerida e pode ser :good, :strong ou :weak (é desnecessário dizer que a última opção não faz o menor sentido, já que qualquer senha será aceita). Já a opção :with define qual o atributo que deverá ser usado na comparação da senha. Se quiser, pode definir um outro atributo:
validates_strength_of :password, :with => :emailTambém é possível proibir senhas que usem determinados caracteres por completo com a opção :exclude. Podemos, por exemplo, evitar que senhas contendo a string asdf sejam usadas:
validates_strength_of :password, :exclude => /asdf/iAlternativamente, você pode definir uma lista de strings que não devem ser utilizadas:
validates_strength_of :password, :exclude => %w[ asdf qwert zxcv ]JavaScript
No HTML, adicione os arquivos que você baixou.
<script src="jquery-1.4.2.js" type="text/javascript"></script>
<script src="password_strength.js" type="text/javascript"></script>
<script src="jquery.strength.js" type="text/javascript"></script>Se você não usa jQuery, pode usar apenas o arquivo password_strength.js e criar o seu próprio adaptador.
A API do JavaScript é essencialmente a mesma, inclusive com as mesmas regras de verificação. Veja:
var strength = PasswordStrength.test("johndoe", "mypass");
strength.isGood();
strength.isStrong();
strength.isWeak();
strength.isValid("good");Você também pode usar a opção :exclude mas, no momento, apenas expressões regulares são aceitas.
var strength = PasswordStrength.test("johndoe", "password with whitespaces", {exclude: /\s/});
strength.isInvalid();Se você usa jQuery, pode utilizar o plugin que já vem com o Password Strength.
$.strength("#username", "#password");A definição acima irá utilizar o campo #username e #password para fazer a validação da senha. Conforme a senha é digitada, uma imagem é colocada ao lado do campo de senha. Por padrão, as imagens utilizadas são /images/{weak,good,strong}.png. Se você quiser, pode alterar esses caminhos:
$.strength.weakImage = "/weak.png";
$.strength.goodImage = "/good.png";
$.strength.strongImage = "/strong.png";Você também pode sobrescrever o callback padrão.
$.strength("#username", "#password", function(username, password, strength){
// do whatever you want
});Se você quiser sobrescrever o callback globalmente, pode fazê-lo da seguinte maneira:
$.strength.callback = function(username, password, strength) {
// do whatever you want
};Qualquer dúvida, mande um comentário!