Introduction
Hi, I'm Take, and I work as an engineer at an in-house development company in Tokyo.
In this article, I'll share what I've learned about generating tokens necessary for secure user authentication using Rubyโs standard library, SecureRandom.
Background
What is SecureRandom?
SecureRandom is a tool used to generate random numbers and strings that are hard to predict. You can learn more about it in this helpful article here.
What is a Token?
A token is a randomly generated string used temporarily to identify a user.
What is a Digest?
During authentication, the data sent is transformed using the same hash function and verified against the stored digest, which is kept on the server side.
Comparing Tokens and Digests
Feature | Token | Digest |
---|---|---|
Purpose | Temporarily stored in the user's browser and used directly for authentication. | Stored in the database and used for token verification. |
Generation Method | Generated using random data functions like SecureRandom.urlsafe_base64 . |
Generated from the token using hash functions like SHA-256 . |
Security | Randomly generated, but can be misused if stolen. | Stored in a hashed form, making it difficult to identify the original token if stolen. |
Generating a Token
The SecureRandom.urlsafe_base64
method generates a safe, random token. This method produces a 22-character string from a set of 64 possible characters (A-Z, a-z, 0-9, "-", "_").
irb(main):001> SecureRandom.urlsafe_base64
=> "TGYseMGxXvuG4tmD08MiAQ"
irb(main):002> SecureRandom.urlsafe_base64
=> "a_xN8Hw0BMuRHrGszl-CLA"
irb(main):003> SecureRandom.urlsafe_base64
=> "AUMBKxwWbV0eMGGEP2LNJg"
Generating a Digest
The token generated is hashed using the User.digest method, and this hashed version (digest) is stored in the database. This makes it difficult to identify the actual token if it were ever leaked.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
This method generates a new token and saves it to the remember_token property of the user instance before updating the tokenโs digest in the remember_digest field.
User Authentication Process
When a user revisits the site, the token saved in the cookies is retrieved, hashed, and verified against the digest stored in the database. This process authenticates the user.
rails console --sandbox
user = User.first
user.remember
TRANSACTION (0.1ms) SAVEPOINT active_record_1
User Update (0.3ms) UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ? [["updated_at", "2024-05-12 05:18:18.739100"], ["remember_digest", "$2a$12$RQayRzS/lv5Je8NDcycI9ut2uMn8uNDMWUZ.H0t1ixBXyRHFn6mYS"], ["id", 1]]
TRANSACTION (0.0ms) RELEASE SAVEPOINT active_record_1
=> true
Conclusion
Through this article, we've explored secure methods of user authentication using tokens and digests, with a focus on SecureRandom for generating safe tokens. Understanding this foundation is crucial for further strengthening security measures.
Thank you for reading! If you liked this article, please give it a "like" ๐.
Top comments (0)