DEV Community

Cover image for ๐Ÿ’Ž Using Ruby's SecureRandom to Strengthen User Authentication
Takehiro_Yamazaki
Takehiro_Yamazaki

Posted on

๐Ÿ’Ž Using Ruby's SecureRandom to Strengthen User Authentication

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.

Golden Security

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)