Sinatra and Session Variables Which Are Not Being Set

Sinatra and session variables which are not being set

If you're using Shotgun, add the following line to the configure block:

set :session_secret, "My session secret"

To quote from rkh, Sinatra's current maintainer:

[Shotgun] will restart the server on every request, thereby regenerate the session secret and thus invalidate your sessions. This has been fixed in current master. Simple fix: set the session_secret option.

NOTE: This fix doesn't work if you use Rack::Session::Pool

session[:id] variable not being picked up within another route from sinatra

Have you tried enable :sessions after you require your sinatra gem in your sinatra app? Not in your controller

Sinatra Sessions Not Persisting as Expected

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

sinatra session members disappear when set while streaming

Sessions work as middleware. When the request comes in the current sessions variables (if any) are read in from wherever they are stored and made available to the rest of the request as a hash. When the request is finished, the middleware persists this hash to whatever session store is being used and the appropriate headers are set on the response. (I’m simplifying somewhat here, but this is basically what happens).

When streaming, the block to stream is called after the response is finished, i.e. after the session middleware has run. This means that although the session hash is still available, and you can set items on it, it is never persisted anywhere and so anything you set here isn’t available in any later requests.

If you are using the default cookie based session store there is little you can do here other than make sure you set your session variables outside the stream block. By the time the stream block is called, all the headers have been written out including the cookie containing the serialized session data.

If you are using a server side session store you could alter the session code so that late updates such as these are persisted. Whether it would be worth it would be another question.

Sessions in Sinatra: Used to Pass Variable

You have a typo in your post route:

session["value"] == @cal
# ^^ compares for equality, does not set.

This will not affect the session, but will just evaluate to either true or (more likely) false.

What sort of object is @cal, and what are you using for your session backing? (Are these cookie-backed sessions, aka Rack::Session::Cookie, enabled via enable :sessions? If so, is your object definitely able to be serialized through Marshal?)

Edit

Yes, if you fix that typo, what you have should work.

Here's a test application that works for me...

require 'sinatra'
enable :sessions
get('/'){ haml :show_and_go }
post '/' do
session["foo"] = [[[1,2],[3,4]],[5,6]]
"Now get it!\n"
end
__END__
@@show_and_go
%p= session["foo"].inspect
%form(method='post' action='/')
%button go

...and here is the testing of it in action. We see that with no cookies you get no session, but once the cookie has been written the very next request has it working. This works just as well in the browser, too:

phrogz$ cat cookies.txt
cat: cookies.txt: No such file or directory

phrogz$ curl http://localhost:4567/ # GET
<p>nil</p>
<form action='/' method='post'>
<button>go</button>
</form>

phrogz$ curl -d "" -c cookies.txt http://localhost:4567 # POST
Now get it!

phrogz$ curl -b cookies.txt http://localhost:4567 # GET, with cookies
<p>[[[1, 2], [3, 4]], [5, 6]]</p>
<form action='/' method='post'>
<button>go</button>
</form>


Related Topics



Leave a reply



Submit