Search code examples
sinatrarackthin

Simple Sinatra Sessions Not Working


According to the Sinatra FAQ, a Sinatra app like this should work:

enable :sessions

class MyApp < Sinatra::Base
  get '/foo' do
    session[:message] = 'Hello World!'
    redirect to('/bar')
  end

  get '/bar' do
$stderr.puts session[:message]
    session[:message]   # => 'Hello World!'
  end
end

given a config.ru like:

require 'sinatra'

require './test.rb' # which contains the above MyApp

run MyApp

and invoking it via:

thin -R config.ru -p 4567 start

While the Sinatra code runs, it is not setting a cookie. You can see this in the curl -vL http://localhost:4567/foo output:

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 4567 (#0)
> GET /foo HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:4567
> Accept: */*
> 
< HTTP/1.1 302 Moved Temporarily
< Content-Type: text/html;charset=utf-8
< Location: http://localhost:4567/bar
< Content-Length: 0
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Connection: keep-alive
* Server thin is not blacklisted
< Server: thin
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:4567/bar'
* Found bundle for host localhost: 0x1180760
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 4567 (#0)
> GET /bar HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:4567
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 0
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Connection: keep-alive
* Server thin is not blacklisted
< Server: thin
< 
* Connection #0 to host localhost left intact

Plus, the $stderr.puts session[:message] is not emitting the message, but rather just a blank line.

Swtiching enable :sessions to the following also has no impact:

use Rack::Session::Cookie, :key => 'rack.session',
                       :domain => 'foo.com',
                       :path => '/',
                       :expire_after => 2592000, # In seconds
                       :secret => 'change_me'

This is with thin 1.6.3, rack 1.6.0, and sinatra 1.4.5.

Where am I going wrong? Beyond being woefully short on sleep right now...

Thanks!


Solution

  • You need to move the enable :sessions line inside your app class:

    class MyApp < Sinatra::Base
      enable :sessions
      #...
    

    With that line where it is now you have enabled sessions for the Sinatra::Application app, which is the app that is run when you use the “classic” style, but that isn’t run here. You need to enable sessions in your app.

    With that change you should see the cookie headers being set, but you will need to use something like curl -vL -b cookie_file -c cookie_file http://localhost:4567/foo to see it actually work with curl (so that the cookies are stored and resent).