20
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- 这就是问题发生的时候。如果我通过它运行 Sinatra http://localhost:4567,一切都会按预期工作。

解决方案

使用Rack::Session::Cookie而不是默认值enable :sessions

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

来自Sinatra 常见问题解答

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

4

5 回答 5

18

我遇到了和你一样的问题:会话正在被清除。

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

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

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

于 2013-10-08T15:18:24.930 回答
5

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

set :session_secret, SESSION_SECRET
enable :sessions

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

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

设置 :session_secret, '超级机密'

于 2016-08-26T07:52:41.457 回答
2

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

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

 set :session_secret, "328479283uf923fu8932fu923uf9832f23f232"
 enable :sessions

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

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

也可以工作,但只是因为它将秘密设置为固定值。

于 2016-09-09T19:37:02.420 回答
0

应@smoyth 的要求,我将我的评论作为单独的答案发布。

只是我的两分钱:这发生在我身上,因为 Rack::Protection模块正在放弃会话。就我而言,这是HttpOrigin失败的。您可能会发现启用登录Rack::Protection以查看此内容很有帮助。我没能做到(我正在使用 Gollum 并且不确定在哪里设置此选项),所以我在Rack::Protection::Base.

于 2021-12-20T09:04:12.393 回答
-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:
于 2013-09-17T08:42:21.600 回答