Sinatra Sessions Not Persisting as Expected
Asked Answered
N

3

6

I'm trying to use redirects and sessions in Sinatra to pass some data around the site. Here's a simplified example, using PrettyPrint for debugging:

require 'pp'

require 'rubygems'
require 'sinatra'

enable :sessions

get '/' do
  session[:foo] = '12345'

  puts 'session1'
  pp session

  redirect to('/redir')
end

get '/redir' do
  puts 'session2'
  pp session
  'hello world'
end

Looking at Thin's output, I see:

>> Listening on 0.0.0.0:4567, CTRL+C to stop
session1
{"session_id"=>
  "ea587d8afdcb2ada64f9b17cdd1fbae7b192dee5dfc2999ff9d323f1528f6a0f",
 "foo"=>"12345"}
127.0.0.1 - - [19/Jul/2011 10:33:24] "GET / HTTP/1.1" 302 - 0.0042
session2
{}
127.0.0.1 - - [19/Jul/2011 10:33:24] "GET /redir HTTP/1.1" 200 11 0.0004

Everything I've seen in the docs suggests that this should work fine. In fact, I never get any session data for /redir, even if I request it directly, and the session persists as you'd expect on subsequent requests for /.

Thoughts?

Negotiation answered 19/7, 2011 at 14:40 Comment(1)
Sinatra sessions are using cookies. Did you try monitoring your HTTP headers (with Firebug, for example) to make sure cookies are going in and out? Also look at this one #5632362 and this one https://mcmap.net/q/1123971/-how-to-use-sinatra-sessionUntrue
F
2

It seems as though the session hash is not loaded until a session variable is referenced. So, for example, you get the expected result if you change the redirect handler to:

get '/redir' do
  puts 'session2'
  puts session[:foo]
  pp session
  'hello world'
end

I guess Sinatra is using the session directly from Rack. A quick peek at the source shows that the session hash is lazily loaded when the [] method (and others) are invoked:

https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb

Flux answered 19/7, 2011 at 16:52 Comment(1)
That works, but it turns out the "proper" way to access members of the session hash is to use session[:foo].inspect.Negotiation
P
12

FWIW, I'm not clear on why this is, but once I moved my Sinatra app to a multi-instance environment, I started having a ton of issues with the session disappearing.

In the end, I found using this syntax worked, whereas the simple 'enable :sessions' or 'set :sessions, true' did not:

use Rack::Session::Cookie, :key => 'rack.session',
                           :path => '/',
                           :secret => 'your_secret'
Philomel answered 17/3, 2012 at 5:44 Comment(0)
F
3

The reason why the format posted by Tom Lianza worked is because by default Sinatra uses

set :session_secret, SecureRandom.hex(64) To select a random secret and since there exists multiple environments, each one will use a different secret resulting in a contradicting cookies. Of course it should be added as an environment variable or Config file that isn't checked into an SVC.

Related Sinatra issue

Flagstad answered 20/2, 2018 at 16:14 Comment(0)
F
2

It seems as though the session hash is not loaded until a session variable is referenced. So, for example, you get the expected result if you change the redirect handler to:

get '/redir' do
  puts 'session2'
  puts session[:foo]
  pp session
  'hello world'
end

I guess Sinatra is using the session directly from Rack. A quick peek at the source shows that the session hash is lazily loaded when the [] method (and others) are invoked:

https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb

Flux answered 19/7, 2011 at 16:52 Comment(1)
That works, but it turns out the "proper" way to access members of the session hash is to use session[:foo].inspect.Negotiation

© 2022 - 2024 — McMap. All rights reserved.