【Ruby】SecureRandomを使ってユーザー認証を強化する方法
はじめに
こんにちは、Takeです。都内の自社開発企業でエンジニアとして働いています。
本記事ではRubyの標準ライブラリであるSecureRandom
を用いて、セキュアなユーザー認証に必要となるトークンを生成する方法について学習した内容を共有します。
前提
SecureRandom
とは
(ざっくりと)推測されにくいランダムな数値や文字列を生成するためのツールのこと。
トークンとは
一時的に生成されるランダムな文字列でユーザーを識別するために活用される。
ダイジェストとは
認証時に送られてきたデータを同じハッシュ関数で変換し、保存されたダイジェストと照合することで認証を行う。
サーバー側で保存される。
トークンとダイジェストの比較
特性 | トークン | ダイジェスト |
---|---|---|
使用目的 | ユーザーのブラウザに一時的に保存され、認証に直接使用される。 | データベースに保管され、トークンの照合に使用される。 |
生成方法 | ランダムなデータ生成関数(SecureRandom.urlsafe_base64 )などを使用して生成される。 |
ハッシュ関数(SHA-256 )を使用してトークンから生成される。 |
安全性 | ランダムに生成されるが、盗まれた場合はそのまま悪用される可能性がある。 | ハッシュ化された形で保存されるため、盗まれても元のトークンを特定することは困難。 |
トークンの生成
SecureRandom.urlsafe_base64メソッドは安全なランダムトークンを生成する。このメソッドは、A-Z、a-z、0-9、"-"、"_"の64種類の文字からランダムに22文字の文字列を生成する。
irb(main):001> SecureRandom.urlsafe_base64
=> "TGYseMGxXvuG4tmD08MiAQ"
irb(main):002> SecureRandom.urlsafe_base64
=> "a_xN8Hw0BMuRHrGszl-CLA"
irb(main):003> SecureRandom.urlsafe_base64
=> "AUMBKxwWbV0eMGGEP2LNJg"
ダイジェストの生成
生成されたトークンはUser.digest
メソッドを用いてハッシュ化され、このハッシュ化されたバージョン(ダイジェスト)がデータベースに保存される。これにより、もしトークンが何らかの方法で漏洩しても、実際のトークンを特定することは困難になる。
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
このメソッドは、新しいトークンを生成してユーザーインスタンスのremember_token
プロパティに保存した後、そのトークンのダイジェストをremember_digest
フィールドに更新する。
ユーザーの認証プロセス
ユーザーがサイトに再訪した場合、保存されているクッキーからトークンを取り出し、送信されたトークンをハッシュ化してデータベース内のダイジェストと照合する。この流れでユーザーの認証が行われる。
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
このメソッドは、Userモデル内で新しいremember_token
を生成し、そのトークンを使ってremember_digest
を計算してデータベースに更新を行います。
user.remember_token
=> "eEpHwgjEMBzs3YVjoAEl6Q"
user.remember_digest
=> "RQayRza$12$0t1ixBXyRHFn6mYSyc0t1ixBXyRHFn6mYSycI9uS/lv5$2t2uMn"
まとめ
本記事を通じて、トークンとダイジェストを用いたユーザー認証の安全な方法を中心に解説してきた。SecureRandom
を使った安全なトークン生成はセキュリティ基盤を強化する効果的な手段である。この概念を理解し、さらなるセキュリティ強化に取り組んでいきたい。
最後に
ここまで読んでいただきありがとうございました!
今回の記事が良かったと思ったらぜひ「いいね」を押していただけると嬉しいです 🎉
noteでも記事を執筆していますので、ぜひチェックしてみてください。
他にもこのようなことについて記載しているのでお読みいただければ幸いです。
最後までお読みいただき、誠にありがとうございました!
Discussion