Sinatra在帖子上清除会话

时间:2013-09-17 08:26:59

标签: ruby sinatra

enable :sessions
set :session_secret, 'secret'

post '/login' do
        session[:loggedInUser] = jsondata['username'].to_s
        puts session[:loggedInUser] + " is the session"
end

此时一切都很好。当我像这样阅读会话时:

get '/debug' do
    session.inspect
end

一切都在那里。但问题来了。当我稍后再提出另一个帖子请求时:

post '/foo' do
    # do nothing
end

会话已清除。

为什么呢?这是一个错误吗?

修改

我已经缩小了问题范围:我通过nginx代理通过Sinatra到http://app.local/backend - 这是问题发生的时候。如果我通过http://localhost:4567运行Sinatra,它将按预期工作。

使用Rack::Session::Cookie代替默认enable :sessions

use Rack::Session::Cookie, :key => "rack.session",
:path => "/backend"
# etc

来自Sinatra FAQ

  

如果您需要为会话设置其他参数,例如到期   date,直接使用Rack :: Session :: Cookie而不是enable:sessions:

4 个答案:

答案 0 :(得分:16)

我遇到了和你一样的问题:会议在帖子上被清除。

我不知道为什么会这样,但这是我的解决方案:

#enable :sessions
use Rack::Session::Cookie, :key => 'rack.session',
                           :path => '/',
                           :secret => 'your_secret'

我实际上只是将enable :sessions位替换为use Rack::Session::Cookie ...,现在世界上一切都很好。

答案 1 :(得分:4)

添加set :session_secret, SESSION_SECRET后,一切正常。

set :session_secret, SESSION_SECRET
enable :sessions

然后我发现,Sinatra的README确实提到了这一点:

  

为了提高安全性,cookie中的会话数据使用会话密钥进行签名。 Sinatra为您生成随机秘密。 但是,由于此秘密会随着应用程序的每次启动而改变,您可能需要自己设置秘密,以便所有应用程序实例共享它

     

设置:session_secret,'超级秘密'

答案 2 :(得分:0)

这是因为Sinatra会在每次启动应用程序时重新生成会话cookie,如果您在apache或机架服务器后运行,可以启动或切换到另一个实例,您将面临此问题。

更简单的解决方案是将秘密设置为固定值,例如:

 set :session_secret, "328479283uf923fu8932fu923uf9832f23f232"
 enable :sessions

建议这样做的另一个答案是:

#enable :sessions
use Rack::Session::Cookie, :key => 'rack.session',
                           :path => '/',
                           :secret => 'your_secret'

同样有效,但仅仅因为它将秘密设置为固定值。

答案 3 :(得分:-3)

我根本没有看到任何问题。这是我的代码。试试这个,看看你是否还有这个问题。

require 'sinatra'

configure do
  enable :sessions
  set :session_secret, 'secret'
end

get '/login' do
  session[:foo] = Time.now
  "Session value set."
end

get '/fetch' do
  "Session value: #{session[:foo]}"
end

get '/foo' do
  "Session value: #{session[:foo]}"
end

get '/logout' do
  session.clear
  redirect '/foo'
end

http://localhost:4567/login #=> Session value set.
http://localhost:4567/fetch #=> Session value: 2013-09-17 09:42:56 +0100
http://localhost:4567/foo #=> Session value: 2013-09-17 09:42:56 +0100
http://localhost:4567/logout #=>(redirects to) http://localhost:4567/foo #=> Session value: