Skip to content

Commit

Permalink
Merge pull request #1161 from jkowens/custom_session_store
Browse files Browse the repository at this point in the history
Add option to set the session middleware when enabling sessions
  • Loading branch information
Zachary Scott authored Aug 9, 2016
2 parents 98990ef + 593cb37 commit 4797c02
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 23 deletions.
60 changes: 38 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pick up if available.
* [Filters](#filters)
* [Helpers](#helpers)
* [Using Sessions](#using-sessions)
* [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
* [Halting](#halting)
* [Passing](#passing)
* [Triggering Another Route](#triggering-another-route)
Expand Down Expand Up @@ -1377,24 +1378,6 @@ get '/:value' do
end
```

Note that `enable :sessions` actually stores all data in a cookie. This
might not always be what you want (storing lots of data will increase your
traffic, for instance). You can use any Rack session middleware: in order to
do so, do **not** call `enable :sessions`, but instead pull in your
middleware of choice as you would any other middleware:

```ruby
use Rack::Session::Pool, :expire_after => 2592000
get '/' do
"value = " << session[:value].inspect
end
get '/:value' do
session['value'] = params['value']
end
```

To improve security, the session data in the cookie is signed with a session
secret. A random secret is generated for you by Sinatra. However, since this
secret will change with every start of your application, you might want to
Expand All @@ -1418,6 +1401,36 @@ domain with a *.* like this instead:
set :sessions, :domain => '.foo.com'
```

#### Choosing Your Own Session Middleware

Note that `enable :sessions` actually stores all data in a cookie. This
might not always be what you want (storing lots of data will increase your
traffic, for instance). You can use any Rack session middleware: in order to
do so, one of the following methods can be used:

```ruby
enable :sessions
set :session_store, Rack::Session::Pool
```

Or to set up sessions with a hash of options:

```ruby
set :sessions, :expire_after => 2592000
set :session_store, Rack::Session::Pool
```

Another option is to **not** call `enable :sessions`, but instead pull in your
middleware of choice as you would any other middleware.

It is important to note that when using this method, session based protection (see 'Configuring attack protection') **will not be enabled by default**. The Rack middleware to do that will also need to be added:

```ruby
use Rack::Session::Pool, :expire_after => 2592000
use Rack::Protection::RemoteToken
use Rack::Protection::SessionHijacking
```

### Halting

To immediately stop a request within a filter or route use:
Expand Down Expand Up @@ -2098,12 +2111,12 @@ set :protection, :except => [:path_traversal, :session_hijacking]
```
By default, Sinatra will only set up session based protection if `:sessions`
has been enabled. Sometimes you want to set up sessions on your own, though. In
that case you can get it to set up session based protections by passing the
`:session` option:
have been enabled. See 'Using Sessions'. Sometimes you may want to set up
sessions "outside" of the Sinatra app, such as in the config.ru or with a
separate Rack::Builder instance. In that case you can still set up session
based protection by passing the `:session` option:
```ruby
use Rack::Session::Pool
set :protection, :session => true
```
Expand Down Expand Up @@ -2236,6 +2249,9 @@ set :protection, :session => true
See 'Using Sessions' section for more information.
</dd>
<dt>session_store</dt>
<dd>The Rack session middleware used. Defaults to <tt>Rack::Session::Cookie</tt>. See 'Using Sessions' section for more information.</dd>
<dt>show_exceptions</dt>
<dd>
Show a stack trace in the browser when an exception happens. Enabled by
Expand Down
3 changes: 2 additions & 1 deletion lib/sinatra/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1709,7 +1709,7 @@ def setup_sessions(builder)
options = {}
options[:secret] = session_secret if session_secret?
options.merge! sessions.to_hash if sessions.respond_to? :to_hash
builder.use Rack::Session::Cookie, options
builder.use session_store, options
end

def detect_rack_handler
Expand Down Expand Up @@ -1781,6 +1781,7 @@ def self.force_encoding(data, *) data end
set :dump_errors, Proc.new { !test? }
set :show_exceptions, Proc.new { development? }
set :sessions, false
set :session_store, Rack::Session::Cookie
set :logging, false
set :protection, true
set :method_override, false
Expand Down
11 changes: 11 additions & 0 deletions test/settings_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,17 @@ def use(middleware, *)
end
end

it 'sets up RemoteToken if sessions are enabled with a custom session store' do
MiddlewareTracker.track do
Sinatra.new {
enable :sessions
set :session_store, Rack::Session::Pool
}.new
assert_include MiddlewareTracker.used, Rack::Session::Pool
assert_include MiddlewareTracker.used, Rack::Protection::RemoteToken
end
end

it 'does not set up RemoteToken if sessions are disabled' do
MiddlewareTracker.track do
Sinatra.new.new
Expand Down

0 comments on commit 4797c02

Please sign in to comment.