From d460c9a25560f43e7c3789abadf7b455053eb686 Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Sun, 23 Nov 2008 15:29:11 +0100 Subject: Add ActiveSupport::MessageVerifier to aid users who need to store tamper-proof messages in cookies etc. This is particularly useful for things like remember-me tokens in web applications and auto-unsubscribe links in emails. --- .../lib/active_support/message_verifier.rb | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 activesupport/lib/active_support/message_verifier.rb (limited to 'activesupport/lib/active_support/message_verifier.rb') diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb new file mode 100644 index 0000000000..f3f905c15e --- /dev/null +++ b/activesupport/lib/active_support/message_verifier.rb @@ -0,0 +1,45 @@ +module ActiveSupport + # MessageVerifier makes it easy to generate and verify messages which are signed + # to prevent tampering. + # + # This is useful for cases like remember-me tokens and auto-unsubscribe links where the + # session store isn't suitable or available. + # + # Remember Me: + # cookies[:remember_me] = @verifier.generate_message([@user.id, 2.weeks.from_now]) + # + # In the authentication filter: + # + # id, time = @verifier.verify_message(cookies[:remember_me]) + # if time < Time.now + # self.current_user = User.find(id) + # end + # + class MessageVerifier + class InvalidSignature < StandardError; end + + def initialize(secret, digest = 'SHA1') + @secret = secret + @digest = digest + end + + def verify_message(signed_message) + data, digest = signed_message.split("--") + if digest != generate_digest(data) + raise InvalidSignature + else + Marshal.load(ActiveSupport::Base64.decode64(data)) + end + end + + def generate_message(value) + data = ActiveSupport::Base64.encode64s(Marshal.dump(value)) + "#{data}--#{generate_digest(data)}" + end + + private + def generate_digest(data) + OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), @secret, data) + end + end +end \ No newline at end of file -- cgit v1.2.3