Skip to content

Instantly share code, notes, and snippets.

@stevehodgkiss
Last active August 29, 2015 14:04
Show Gist options
  • Save stevehodgkiss/5ee4db3a76f8a4d3ff23 to your computer and use it in GitHub Desktop.
Save stevehodgkiss/5ee4db3a76f8a4d3ff23 to your computer and use it in GitHub Desktop.
# Patches Rails signed cookie jar to allow an old secret to be
# transitioned (read). Rails will re-generate the session
# cookie with the new secret for the response.
#
# https://github.com/rails/rails/blob/v3.2.18/actionpack/lib/action_dispatch/middleware/cookies.rb#L279-L332
#
# An alternative with no monkey patching - https://github.com/envato/rails_session_key_rotator
fail "This patch will need updating if it is to be used with Rails 4" if Rails.version[0] != '3'
class ActionDispatch::Cookies::SignedCookieJar
cattr_accessor :old_secret
def [](name)
verify(@verifier, name) ||
(old_secret && verify(old_verifier, name))
end
private
def verify(verifier, name)
if signed_message = @parent_jar[name]
verifier.verify(signed_message)
end
rescue ActiveSupport::MessageVerifier::InvalidSignature
nil
end
def old_verifier
ActiveSupport::MessageVerifier.new(old_secret)
end
end
require 'spec_helper'
describe ActionDispatch::Cookies::SignedCookieJar do
let(:secret) { '301c44ccf472e49b2d2fe6fe826a2c7b' }
let(:old_secret) { '401364a8d5957b37c78c2b08751e0a6e' }
let(:jar) { { 'session' => old_cookie } }
let(:session_data) { { 'session_id' => 1 } }
let(:old_cookie) { ActiveSupport::MessageVerifier.new(old_secret).generate(session_data) }
let(:new_cookie) { ActiveSupport::MessageVerifier.new(secret).generate(session_data) }
subject(:signed_cookie_jar) { described_class.new(jar, secret) }
before do
@old_secret = ActionDispatch::Cookies::SignedCookieJar.old_secret
ActionDispatch::Cookies::SignedCookieJar.old_secret = old_secret
end
it 'reads the old cookie' do
expect(signed_cookie_jar['session']).to eq session_data
end
after do
ActionDispatch::Cookies::SignedCookieJar.old_secret = @old_secret
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment