Provides utility methods to read and write cookies shared with a Rails app
MIT License
This is a Ruby-only (2.0 or later) implementation of utility methods to manage cookies generated by a Rails app. It doesn't depend on any external gems.
Just tell RailsCompatibleCookiesUtils the Rails app secret key and it will be able to handle signed and encrypted cookies (it can both read and write those values).
This is useful if you intend to share your cookies (or session) among different Ruby web applications (they could be even running in the same domain behind a proxy for example) when at least one of the applications is not a Rails one.
Or you could use this if you are switching from Rails to another Ruby web framework and want to deal with old valid sessions after deploying (either if it's a temporary strategy or you want to keep this encrypting and signing algorithms permanently).
Add this line to your application's Gemfile:
gem 'rails_compatible_cookies_utils'
And then execute:
$ bundle
Or install it yourself as:
$ gem install rails_compatible_cookies_utils
You may test the following examples in a REPL with bin/console
.
Creating an instance using the default serializer in Rails 5 generated applications (JSON):
cookies_utils = RailsCompatibleCookiesUtils.new 'secret_key_base'
Usually you'll pass the Rails app secret_key_base
(Rails.application.config.secret_key_base
)
you want to share cookies with. You can also generate a Rails-like random secret key for other
purposes if you want:
secret_key_base = SecureRandom.hex 64
In previous Rails releases the default serializer was Marshal. If your app uses it, initialize it this way:
cookies_utils = RailsCompatibleCookiesUtils.new 'secret_key_base', serializer: Marshal
An instance of RailsCompatibleCookiesUtils is not thread-safe, so ensure to create a new instance for each thread using such an instance or make the calls in within a mutex synchronized block.
This would be the equivalent of cookies.encrypted['_myapp_session']
:
raw_cookie_string = env['HTTP_COOKIE'] # this would be considering a Rack app
cookies_utils.decrypt_cookie_key raw_cookie_string, '_myapp_session'
Or if you already have the parsed and unescaped cookie value:
value = cookies_utils.cookies(env['HTTP_COOKIE'])['_myapp_session']
# you may actually get the value from somewhere else
cookies_utils.decrypt value
require 'cgi'
value = { test: true }
cookie = CGI::Cookie.new 'some_key', cookies_utils.encrypt value
# or using a framework helper:
# cookies['some_key'] = cookies_utils.encrypt value
cookies_utils.decrypt(cookies_utils.encrypt 'secret') == 'secret'
Rails also allows you to just sign a cookie value without encrypting it
(cookies.signed['key'] = 'value'
). To verify and decode the value:
cookies_utils.signed_cookie_key env['HTTP_COOKIE'], 'some_key'
# or cookies_utils.verify_and_deserialize signed_serialized_value
Serialize and sign a cookie value with:
require 'cgi'
value = { test: true }
cookie = CGI::Cookie.new 'some_key', cookies_utils.serialize_and_sign value
# or using a framework helper:
# cookies['some_key'] = cookies_utils.serialize_and_sign value
cookies_utils.verify_and_deserialize(cookies_utils.serialize_and_sign 'secret') == 'secret'
If the value is invalid decrypt_cookie_key
, decrypt
, signed_cookie_key
,
verify_and_deserialize
and serialize_and_sign
will all return nil. All of
them have a bang variant which will raise RailsCompatibleCookiesUtils::InvalidSignature
instead in those cases (like decrypt!
).
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub.
The gem is available as open source under the terms of the MIT License.