Esto es lo que estoy usando. El token no necesariamente tiene que ser escuchado para adivinar, es más como un identificador de URL corto que cualquier otra cosa, y quiero que sea breve. He seguido algunos ejemplos que he encontrado en línea y, en caso de colisión, creo que el siguiente código recreará el token, pero no estoy muy seguro. Sin embargo, tengo curiosidad por ver mejores sugerencias, ya que esto se siente un poco áspero por los bordes.
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
La columna de mi base de datos para el token es un índice único y también lo estoy usando validates_uniqueness_of :token
en el modelo, pero debido a que estos se crean en lotes automáticamente en función de las acciones del usuario en la aplicación (hacen un pedido y compran los tokens, esencialmente), es no es factible que la aplicación arroje un error.
Supongo que también podría reducir la posibilidad de colisiones, agregar otra cadena al final, algo generado en función del tiempo o algo así, pero no quiero que el token se alargue demasiado.
fuente
loop do
(tipo de bucle "while ... do") en este caso (donde se requiere que el loop se ejecute al menos una vez) en lugar debegin...while
(tipo de bucle "do ... while")?ModelName
del método? Tal vez reemplazarlo con en suself.class
lugar? De lo contrario, no es muy reutilizable, ¿verdad?Ryan Bates usa un poco de código en sus invitaciones de Railscast en beta . Esto produce una cadena alfanumérica de 40 caracteres.
fuente
Digest::SHA1.hexdigest([Time.now, rand].join)[0..10]
hexdigest
cualquier IP dada.Esto podría ser una respuesta tardía, pero para evitar el uso de un bucle, también puede llamar al método de forma recursiva. Se ve y se siente un poco más limpio para mí.
fuente
Hay algunas formas bastante ingeniosas de hacer esto demostradas en este artículo:
https://web.archive.org/web/20121026000606/http://blog.logeek.fr/2009/7/2/creating-small-unique-tokens-in-ruby
Mi lista favorita es esta:
fuente
if self.new_record? and self.access_token.nil?
... ¿es eso lo que está comprobando para asegurarse de que el token no esté almacenado?validates_uniqueness_of :token
y agregue un índice único a la tabla con una migración.Si quieres algo que sea único, puedes usar algo como esto:
sin embargo, esto generará una cadena de 32 caracteres.
Sin embargo, hay otra manera:
por ejemplo, para id como 10000, el token generado sería como "MTAwMDA =" (y puedes decodificarlo fácilmente para id, solo crea
fuente
random_string = Digest::MD5.hexdigest("#{ActiveSupport::SecureRandom.hex(10)}-#{DateTime.now.to_s}-#{id}")[1..6]
donde ID es la ID del token.Base64::encode64(id.to_s)
derrota el propósito de usar un token. Lo más probable es que esté usando un token para ocultar la identificación y hacer que el recurso sea inaccesible para cualquier persona que no tenga el token. Sin embargo, en este caso, alguien podría simplemente correrBase64::encode64(<insert_id_here>)
e instantáneamente tendrían todos los tokens para cada recurso en su sitio.string = (Digest::MD5.hexdigest "#{SecureRandom.hex(10)}-#{DateTime.now.to_s}")
Esto puede ser útil:
Si desea eliminar cualquier carácter especial que se ponga en el primer argumento '+ / =' y cualquier carácter puesto en el segundo argumento '0aZ' y 15 es la longitud aquí.
Y si desea eliminar los espacios adicionales y el nuevo carácter de línea, agregue cosas como:
Espero que esto ayude a cualquiera.
fuente
SecureRandom.urlsafe_base64
logra lo mismo también.puedes usar has_secure_token https://github.com/robertomiranda/has_secure_token
es realmente simple de usar
fuente
has_secure_token
viene con Rails 5, pero estaba usando 4.x. He seguido los pasos de este artículo y ahora me funciona.Intenta de esta manera:
A partir de Ruby 1.9, la generación de uuid está integrada. Usa la
SecureRandom.uuid
función.Generando Guías en Ruby
Esto fue útil para mi
fuente
Para crear un GUID apropiado, mysql, varchar 32
fuente
SecureRandom.uuid.tr('-','').upcase
. Consulte este enlace para comparar tr y gsub.fuente
Creo que el token debe manejarse como una contraseña. Como tal, deben estar encriptados en DB.
Estoy haciendo algo como esto para generar un nuevo token único para un modelo:
fuente