redis-session-store
redis-session-store copied to clipboard
Make low level session methods public
Recently, while writing some code to access session data at a low level, we ran into an issue with RedisSessionStore
because it defines the following low level session methods (and aliases) as private
:
-
#get_session
-
#find_session
-
#set_session
-
#write_session
-
#destroy_session
-
#delete_session
These methods are marked as private
in the various inheritance trees of RedisSessionStore
(via ActionDispatch::Session::AbstractStore
):
- In Rails 4, which uses Rack 1.6, the low level session methods are defined (and marked as private) in
Rack::Session::Abstract::ID
- In Rails 5, which uses Rack 2.0 the low level session methods are defined (and marked as private) in
Rack::Session::Abstract::Persisted
.
So at first glance, it seems that RedisSessionStore
is correct in maintaining the private
visibility level.
The problem, however, is that the vast majority of real world session store implementations override the parent visibility settings and mark these low level session methods as public
.
A non exhaustive list of Rack-based session stores in the wild where these methods are public, not private:
-
Rack::Session::Abstract::ID
in Rack >2.0 (in https://github.com/rack/rack/blob/2.0.1/lib/rack/session/abstract/id.rb#L414-L431) -
Rack::Session::Pool
(in https://github.com/rack/rack/blob/master/lib/rack/session/pool.rb#L44-L66) -
Rack::Session::Memcache
(in https://github.com/rack/rack/blob/master/lib/rack/session/memcache.rb#L49-L76) -
ActionDispatch::Session::CacheStore
since Rails 3.2 (in https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/session/cache_store.rb#L20-L43) -
ActionDispatch::Session::MemcacheStore
viaRack::Session::Dalli
, which it inherits from (in https://github.com/petergoldstein/dalli/blob/v2.7.6/lib/rack/session/dalli.rb#L22-L34 and https://github.com/petergoldstein/dalli/blob/v2.7.6/lib/rack/session/dalli.rb#L43-L71) -
Rack::Session::Redis
, used by the redis-store gem (in https://github.com/redis-store/redis-rack/blob/master/lib/rack/session/redis.rb#L45-L71)
As a counter example, ActiveRecordSession
is the one session store I could find in the wild that preserves private visibility for these methods in https://github.com/rails/activerecord-session_store/blob/master/lib/action_dispatch/session/active_record_store.rb#L68-L120)
In short, RedisSessionStore
's marking these methods as private, though consistent with its inheritance tree in both recent versions of Rails, is an outlier in the real world of session store implementations, including all of the persistent stores that are bundled with Rails.
The attached PR simply moves the low-level session methods to the public area of the RedisSessionStore
class definition and adjusts the tests accordingly (i.e. so that they use the now public methods instead of send
).
In addition to being consistent with other session store APIs in the wild, it's very helpful to be able to have proper access to the low level session store outside the context of a specific request. 😄
Hi, this is very important commit. @jsdalton can you please rebase it. With master branch of rails we are receiving error
NoMethodError (private method
delete_session' called for #RedisSessionStore:0x0000555c9eed60c0):`
and making methods public resolve this.
@jsdalton can you please rebase your branch and resolve conflict
@Jesterovskiy can you please review and change this PR?