2012-04-17 2 views
4

Я успешно устранил проблему, когда члены сессии не были доступны, даже если они были установлены, и хотели бы знать, почему это происходит. Мое положение может быть описано как:Участники сеанса Sinatra «исчезают»

  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: Я предполагаю, что мой печенье был кэшируются без значения :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 

Я хотел бы использовать кэширование и до сих пор мое печенье в силе.

+0

Вы установили секретный ключ сеанса? set: session_secret, 'super secret' – mscccc

+0

У меня возникла проблема, когда члены сессии существуют, когда я запускаю свое приложение Sinatra локально, но которое исчезает при работе на Heroku. Я пробовал использовать oAuth и теперь Koala для взаимодействия с Facebook, и оба заканчивают тем же вопросом. –

ответ

1

Трудно видеть, что происходит, не зная всех деталей, но существует простое правило, которое вы, скорее всего, нарушаете: не используйте http-кеширование для действий, которые должны что-то делать (кроме как только показать страницу) , Когда HTTP-кеширование включено, ваш браузер даже не пытается перезагрузить страницу и отображает ее из кеша браузера.

Cookies не кэшируются в любом месте, единственное cache_control делает устанавливает CacheControl HTTP значение ответа

В вашем случае лучшее, что вы можете сделать, это добавить список маршрутов, которые не имеют действию страницы на ваш перед блоком :

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

Скорее всего, вы будете иметь очень ограниченный набор маршрутов, где вы можете извлечь выгоду из кэширования HTTP

+0

Связано: вы не должны использовать ': public ', если ваш ответ включает или иным образом зависит от любого пользовательского или сеансового. Обычно я устанавливаю промежуточное программное обеспечение специально для ресурсов, которые я хочу кэшировать, - который удаляет все входящие файлы cookie и данные сеанса, чтобы я случайно не мог ссылаться на что-то. – willglynn

1

парень по имени Ари Браун (машет Ари), который не является членом здесь, но заслуживает заслуги в этом Ответ, указал мне на правильное решение, которое, согласно 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.Так я и пошел, поскольку он предлагает большую гибкость в настройке.

Причина, по которой эта работа заключается в том, что промежуточное программное обеспечение контроллера кэш-памяти обрабатывает запросы на несколько экземпляров сервера и не устанавливает секретный сеанс, это просто делает один сервер на одном сервере и тем самым нарушает сеансы.

Смежные вопросы