I want to generate a token in my controller for a user in the "user_info_token" column. However, I want to check that no user currently has that token. Would this code suffice?
begin @new_token = SecureRandom.urlsafe_base64 user = User.find_by_user_info_token(@new_token) end while user != nil @seller.user_info_token = @new_token
Or is there a much cleaner way to do this?
If your token is long enough and generated by a cryptographically secure [pseudo-]random number generator, then you do not need to verify that the token is unique. You do not need to generate tokens in a loop.
16 raw source bytes is long enough for this effective guarantee. When formatted for URL-safety, the result will be longer.
# Base-64 (url-safe) encoded bytes, 22 characters long SecureRandom.urlsafe_base64(16) # Base-36 encoded bytes, naturally url-safe, ~25 characters long SecureRandom.hex(16).to_i(16).to_s(36) # Base-16 encoded bytes, naturally url-safe, 32 characters long SecureRandom.hex(16)
This is because the probability that the 16-byte or 128-bit token is nonunique is so vanishingly small that it is virtually zero. There is only a 50% chance of there being any repetitions after approximately 264 = 18,446,744,073,709,551,616 = 1.845 x 1019 tokens have been generated. If you start generating one billion tokens per second, it will take approximately 264/(109*3600*24*365.25) = 600 years until there is a 50% chance of there having occurred any repetitions at all.
But you're not generating one billion tokens per second. Let's be generous and suppose you were generating one token per second. The time frame until a 50% chance of even one collision becomes 600 billion years. The planet will have been swallowed up by the sun long before then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With