我已经成功解决了会话成员无法使用的问题,即使它们已经设置并且想知道它为什么会发生。我的情况可以描述为:
:session
的Sinatra应用。:ret_url
会话成员,以便应用程序知道在授权后返回的位置。这在本地运行时完美无缺,但: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仍然有效。
答案 0 :(得分:1)
很难在不知道所有细节的情况下看到发生了什么,但有一个简单的规则,你最有可能违反:不要在应该做某事的动作上使用http缓存(除了显示页面)。启用http缓存后,您的浏览器甚至不会尝试重新加载页面并从浏览器缓存中呈现它。
Cookie不会缓存在任何地方,cache_control唯一做的就是设置CacheControl http响应值
在您的情况下,您可以做的最好的事情是将没有操作页面的路线列表添加到您之前的块中:
before '/my/static/page' do
cache_control :public, :must_revalidate, :max_age => 60
end
很可能您将拥有非常有限的路线集,您可以从中受益于http缓存
答案 1 :(得分:1)
一位名叫阿里·布朗(Ari Brown)的小伙子(在Ari滔滔不绝),他不是这里的会员,但应该得到这个答案,我指出了正确的解决方案,按照the Sinatra FAQ,不要使用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
中,一切顺利。
我还在this post中注意到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
方法使用环境变量策略。这就是我的方式,因为它提供了更多的配置灵活性。
这些工作的原因是缓存控制器中间件将请求发送到多个服务器实例并且没有设置会话密钥,它只是为每个服务器创建一个,从而打破了会话。