4

我已经成功解决了会话成员不可用的问题,即使他们已设置并且想知道为什么会发生这种情况。我的情况可以描述为:

  1. Sinatra 应用程序使用:session.
  2. 使用 oAuth 授权用户并在此过程中设置:ret_url会话成员,以便应用知道在身份验证后返回到哪里。
  3. 服务器是 Cedar 堆栈上的独角兽(Heroku)

这在本地运行时非常有效,但:ret_url会话成员完全从 Heroku 的会话中消失了。我发现如果我删除了这段代码,它可以解决问题:

  before do
    cache_control :public, :must_revalidate, :max_age => 60
  end

问题 1:我猜我的 cookie 在没有:ret_url值的情况下被缓存,这就是它被破坏的原因?

问题2:我在下面的路由条件代码中设置了会话成员,这是错误的地方吗?

  # redirect users to login if necessary
  set(:auth) do |access_token|      
    condition do

      if request.request_method == 'GET'
        session[:ret_url] = request.path_info 
      end

      redirect '/' unless user_logged_in?
    end
  end

我想使用缓存并且我的 cookie 仍然有效。

4

2 回答 2

1

一个名叫 Ari Brown(向 Ari 挥手)的小伙子,他不是这里的成员,但这个答案值得称赞,他指出了正确的解决方案,根据Sinatra 常见问题解答,不使用enable :sessions而是use Rack::Session::Cookie作为每

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

我已将此添加到我的config.ru中,一切都很好。

我还注意到在这篇文章中的替代建议set :session_secret, 'change_me',实际上,通过环境变量来做到这一点,即:

$ heroku config:add SESSION_KEY=a_longish_secret_key

然后在你的应用程序中

enable :sessions
set :session_secret, ENV['SESSION_KEY'] || 'change_me'

显然,您也可以将环境变量策略与该Rack::Session::Cookie方法一起使用。这就是我采用的方式,因为它提供了更大的配置灵活性。

这些工作的原因是缓存控制器中间件将请求发送到多个服务器实例,并且没有设置会话秘密,它只是为每个服务器创建一个,从而中断会话。

于 2013-02-19T22:23:46.893 回答
1

在不了解所有细节的情况下很难看到发生了什么,但有一条简单的规则您很可能会违反:不要在应该做某事的操作上使用 http 缓存(除了显示页面之外)。当 http 缓存打开时,您的浏览器甚至不会尝试重新加载页面并从浏览器缓存中呈现它。

Cookie 不会在任何地方缓存,cache_control 唯一要做的就是设置 CacheControl http 响应值

在您的情况下,您可以做的最好的事情是将具有无操作页面的路线列表添加到您的 before 块中:

before '/my/static/page' do
  cache_control :public, :must_revalidate, :max_age => 60
end

很可能您将拥有非常有限的一组路由,您可以从这些路由中受益于 http 缓存

于 2012-09-22T17:28:36.180 回答