-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cookie-base session store auto-upgrade #9978
Conversation
Seems like something that should be in the API docs too, especially if it's that important. |
@steveklabnik can you point me to where you think the right spot might be? I'll happily update this PR with more docs. |
Hmm. Yeah, I'm not sure where the best place to put them would be. Maybe @fxn has a better idea. It just seems odd that the upgrade guide would have the docs, and the docs would point to the guide, you know? :) |
Totally, @steveklabnik -- this is an important setting, so let's make sure it's easy to read more about it :) |
else | ||
EncryptedCookieJar.new(self, @key_generator, @options) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can omit the begin...end
wrapper
Love this. Thanks @trevorturk. +1 on the future work, too. Each are good bite-sized PRs. |
…kies; Automatically configure cookie-based sessions to use the best cookie jar given the app's config
@jeremy I removed the unnecessary begin/end, but left the private spacing because the style matches the rest of the file. I'll change this for the entire file in a refactoring commit as part of my upcoming further work pull requests. I rebased, and I think this is ready to merge. We can improve the docs separately. Thanks for the feedback! |
@trevorturk PR looks great. So after applying this we would have a way to use encrypted, signed and the upgrading path. The only drawback I see is you're not able to use signed cookies only without warnings. |
Thanks for reviewing, @spastorino! After applying this, the cookie-based session store would be automatically configured to use the best possible cookie store given the app's configuration . The logic would work like this:
You would still be able to use |
@trevorturk exactly, the warn raises if you don't set secret_key_base. So users are not able to use signed cookie store for sessions without warnings. |
Cookie-base session store auto-upgrade
Thanks @spastorino! We had a chat and did a benchmark showing no significant performance impact for using encrypted session cookies versus signed. So, the recommendation is to reduce the number of configuration options for users and to choose the best cookie store we can, given their app's config. Here's the benchmark: require 'benchmark'
require 'active_support/key_generator'
require 'active_support/message_verifier'
require 'active_support/message_encryptor'
Benchmark.bm do |r|
N = 100000
r.report("signed") do
key_generator = ActiveSupport::DummyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33')
secret = key_generator.generate_key('signed cookie salt')
verifier = ActiveSupport::MessageVerifier.new(secret)
signed_message = verifier.generate('test')
N.times { verifier.verify(signed_message) }
end
r.report("encrypted") do
key_generator = ActiveSupport::KeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33')
secret = key_generator.generate_key('encrypted cookie salt')
sign_secret = key_generator.generate_key('encrypted cookie salt')
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
encrypted_message = encryptor.encrypt_and_sign('test')
N.times { encryptor.decrypt_and_verify(encrypted_message) }
end
end
# user system total real
# signed 3.240000 0.010000 3.250000 ( 3.263722)
# encrypted 5.450000 0.010000 5.460000 ( 5.472302) |
Great work @trevorturk! If you wanted to convert from using Marshal to JSON for session serialization that'd be cool too ;) |
Nevermind... didn't read this PR. |
Changes:
secret_key_base
is set, signed if onlysecret_token
is set.EncryptedCookieStore
andUpgradeSignatureToEncryptionCookieStore
cookie-based session stores, so we leave only the existingconfig.session_store :cookie_store
option and remove the two new options introduced in 4.0.0.beta1:encrypted_cookie_store
andupgrade_signature_to_encryption_cookie_store
.secret_key_base
andsecret_token
are set. Simply upgrade to the new key generator if onlysecret_token
is set. (Pull request Transparently upgrade signed cookies when setting secret_key_base #9909 took care of transparently upgrading signed cookies to use the new key generator.)Reasoning:
The signed cookie jar has changed to use the new Rails-internal key generator, so you are discouraged from having a known/shared secret for signing cookies / sharing sessions.
If signed cookies and signed session cookies are considered internal to Rails, then we can upgrade from signed to encrypted automatically if they opt-in by setting
secret_key_base
.If that all makes sense, then we can just have the one session store for Rails:
cookie_store
. This reduces the number of config options and allows us to state the caveats around upgrading plainly in one place./cc @jeremy @spastorino @neerajdotname
@fxn (or someone else interested in documentation) I'm wondering if we should include a link to the upgrade guide, which is where the caveats/warnings/etc about setting
secret_key_base
are currently.Should we use: http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html or something? Should we just leave this as-is?
Further possible work:
I'd like to continue with a bit more work here, if these ideas make sense:
name
instead ofkey
when referring to cookies. We use both now and @jeremy prefersname
which is fine by me. Also standardizeprivate
spacing as per JK's comments.PermanentCookieJar
's[]
method, which may have been broken in 2b773e1. It's confusingkey
andname
. I'm not sure why there's no failing test.DummyKeyGenerator
toLegacyKeyGenerator
-- "dummy" isn't a very descriptive name. I've settled on "legacy" to refer to signed stuff generated by Rails 3.x. I'm open to other names, but I'd like to move away from "dummy".Dummy/LegacyKeyGenerator
in 4.1. I think we should keep this around a bit longer to ensure that people can upgrade from 3.2.x to 4.1.x etc. There's "fixme" comments in place that I'd like to remove.Dummy/LegacyKeyGenerator
where it makes sense instead ofMessageVerifier
directly. Anything referring to signed cookies should useDummy/LegacyKeyGenerator
, I believe.