Aqui está o que estou usando. O token não precisa necessariamente ser ouvido para adivinhar; é mais como um identificador de URL curto do que qualquer outra coisa, e eu quero mantê-lo curto. Segui alguns exemplos que encontrei on-line e, no caso de uma colisão, acho que o código abaixo recriará o token, mas não tenho certeza. Estou curioso para ver melhores sugestões, no entanto, pois isso parece um pouco áspero nas bordas.
def self.create_token
random_number = SecureRandom.hex(3)
"1X#{random_number}"
while Tracker.find_by_token("1X#{random_number}") != nil
random_number = SecureRandom.hex(3)
"1X#{random_number}"
end
"1X#{random_number}"
end
Minha coluna do banco de dados para o token é um índice exclusivo e também estou usando validates_uniqueness_of :token
no modelo, mas como eles são criados em lotes automaticamente com base nas ações de um usuário no aplicativo (eles fazem um pedido e compram os tokens, essencialmente), é não é possível que o aplicativo gere um erro.
Acho que eu também poderia reduzir a chance de colisões, acrescentar outra sequência no final, algo gerado com base no tempo ou algo assim, mas não quero que o token fique muito tempo.
fonte
loop do
(tipo de loop "while ... do") deve ser usada neste caso (onde o loop é necessário para executar pelo menos uma vez) em vez debegin...while
(tipo de loop "do ... while")?ModelName
método? Talvez substitua porself.class
? Caso contrário, não é muito reutilizável, é?Ryan Bates usa um bom código em seu Railscast em convites beta . Isso produz uma cadeia alfanumérica de 40 caracteres.
fonte
Digest::SHA1.hexdigest([Time.now, rand].join)[0..10]
hexdigest
para qualquer IP.Pode ser uma resposta tardia, mas para evitar o uso de um loop, você também pode chamar o método recursivamente. Parece e parece um pouco mais limpo para mim.
fonte
Existem algumas maneiras bastante lisas de fazer isso demonstradas neste artigo:
https://web.archive.org/web/20121026000606/http://blog.logeek.fr/2009/7/2/creating-small-unique-tokens-in-ruby
O meu favorito listado é o seguinte:
fonte
if self.new_record? and self.access_token.nil?
... é isso que está verificando para garantir que o token ainda não esteja armazenado?validates_uniqueness_of :token
e adicionar um índice exclusivo à tabela com uma migração.Se você deseja algo único, pode usar algo como isto:
no entanto, isso gerará uma sequência de 32 caracteres.
No entanto, existe outra maneira:
por exemplo, para ID como 10000, o token gerado seria "MTAwMDA =" (e você pode decodificá-lo facilmente para ID, basta fazer
fonte
random_string = Digest::MD5.hexdigest("#{ActiveSupport::SecureRandom.hex(10)}-#{DateTime.now.to_s}-#{id}")[1..6]
onde ID é o ID do token.Base64::encode64(id.to_s)
anula o propósito de usar um token. Provavelmente, você está usando um token para ocultar a identificação e tornar o recurso inacessível para quem não possui o token. No entanto, nesse caso, alguém poderia simplesmente executarBase64::encode64(<insert_id_here>)
e teria instantaneamente todos os tokens para todos os recursos do seu site.string = (Digest::MD5.hexdigest "#{SecureRandom.hex(10)}-#{DateTime.now.to_s}")
Isso pode ser útil:
Se você deseja remover qualquer caractere especial que seja colocado no primeiro argumento '+ / =' e qualquer caractere colocado no segundo argumento '0aZ' e 15 é o comprimento aqui.
E se você deseja remover os espaços extras e o caractere de nova linha, adicione coisas como:
Espero que isso ajude alguém.
fonte
SecureRandom.urlsafe_base64
consegue a mesma coisa também.você pode usuário has_secure_token https://github.com/robertomiranda/has_secure_token
é realmente simples de usar
fonte
has_secure_token
vem com o Rails 5, mas eu estava usando o 4.x. Eu segui as etapas deste artigo e agora funciona para mim.Tente desta maneira:
A partir do Ruby 1.9, a geração de uuid é incorporada. Use a
SecureRandom.uuid
funçãoGerando Guids em Ruby
Isso foi útil para mim
fonte
Para criar um GUID adequado, mysql, varchar 32
fonte
SecureRandom.uuid.tr('-','').upcase
. Verifique este link para comparar entre tr e gsub.fonte
Eu acho que o token deve ser tratado como a senha. Como tal, eles devem ser criptografados no banco de dados.
Estou fazendo algo assim para gerar um novo token exclusivo para um modelo:
fonte