Controllers
Sessions
Kindly borrowed from Sinatra's docs :)
A session is used to keep state during requests. If activated, you have one session hash per user session:
enable :sessions
get '/' do
"value = #{session[:value].inspect}"
end
get '/:value' do
session[:value] = params[:value]
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 by passing it to the
sessions setting:
set :sessions, use: Rack::Session::Pool, config: { same_site: :lax, expire_after: 2592000 }
get '/' do
"value = #{session[:value].inspect}"
end
get '/:value' do
session[:value] = params[:value]
end
With use:, cookie options such as same_site and secure go in config:.
Rack::Session::Pool keeps sessions in the memory of one process, so with Puma
workers, several Falcon processes or several servers, use a store they share.
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 set the secret yourself, so all your application instances share it:
configure :production do
set :session_secret, ENV.fetch('SESSION_SECRET')
end
The secret must be at least 64 bytes long. New projects set a random one in
config/apps.rb. Generate your own with:
$ ruby -rsecurerandom -e 'puts SecureRandom.hex(64)'
If you want to configure it further, you may also store a hash with options in
the sessions setting:
set :sessions, domain: 'foo.com'
To share your session across other apps on subdomains of foo.com, prefix the
domain with a . like this instead:
set :sessions, domain: '.foo.com'
Cookie flags
The same hash sets the cookie's SameSite and Secure attributes:
set :sessions, same_site: :lax, secure: true
Use set :sessions in place of enable :sessions, not after it: a later
enable :sessions sets the setting back to true and drops the options.
same_site takes :lax, :strict or :none. Apps generated by Padrino use
same_site: :lax. Browsers drop a same_site: :none cookie unless it is also
secure: true. The cookie is also HttpOnly by default.
secure: true tells the browser to send the cookie only over HTTPS. Rack also
skips saving the session when it sees a plain HTTP request, so over HTTP every
request starts with an empty session, and logins and CSRF tokens stop working.
Turn it on only where the site is served over HTTPS, for example in production:
set :sessions, same_site: :lax
configure :production do
set :sessions, same_site: :lax, secure: true
end
If a proxy or load balancer handles TLS and talks to the app over HTTP, it must
send the X-Forwarded-Proto: https header so that Rack sees the request as
HTTPS.