Синатра не настаивает, как ожидалось
Я пытаюсь использовать редиректы и сеансы в Sinatra для передачи некоторых данных по сайту. Вот упрощенный пример использования PrettyPrint для отладки:
require 'pp'
require 'rubygems'
require 'sinatra'
enable :sessions
get '/' do
session[:foo] = '12345'
puts 'session1'
pp session
redirect to('/redir')
end
get '/redir' do
puts 'session2'
pp session
'hello world'
end
Глядя на вывод Thin, я вижу:
>> Listening on 0.0.0.0:4567, CTRL+C to stop
session1
{"session_id"=>
"ea587d8afdcb2ada64f9b17cdd1fbae7b192dee5dfc2999ff9d323f1528f6a0f",
"foo"=>"12345"}
127.0.0.1 - - [19/Jul/2011 10:33:24] "GET / HTTP/1.1" 302 - 0.0042
session2
{}
127.0.0.1 - - [19/Jul/2011 10:33:24] "GET /redir HTTP/1.1" 200 11 0.0004
Все, что я видел в документах, говорит о том, что это должно работать нормально. На самом деле, я никогда не получаю никаких данных сеанса для /redir
, даже если я запрашиваю их напрямую, и сеанс сохраняется, как и следовало ожидать при последующих запросах для /
.
Мысли?
3 ответа:
Похоже, что хэш сеанса не загружается до тех пор, пока не появится ссылка на переменную сеанса. Так, например, вы получите ожидаемый результат, если измените обработчик перенаправления на:
get '/redir' do puts 'session2' puts session[:foo] pp session 'hello world' end
Я думаю, Синатра использует сеанс непосредственно из стойки. Быстрый взгляд на источник показывает, что хэш сеанса лениво загружается при вызове метода [] (и других):
Https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb
FWIW, я не совсем понимаю, почему это так, но как только я переместил свое приложение Sinatra в среду с несколькими экземплярами, у меня появилось множество проблем с исчезновением сеанса.
В конце концов, я нашел, используя этот синтаксис работал, а просто 'включить :сеансов' или 'set :занятия, правда не:
use Rack::Session::Cookie, :key => 'rack.session', :path => '/', :secret => 'your_secret'
Причина, почему формат написал Тома Лианза работал, потому что по умолчанию Синатра использует
set :session_secret, SecureRandom.hex(64)
Чтобы выбрать случайный секрет, и поскольку существует несколько сред, каждая из них будет использовать другой секрет, приводящий к противоречивым куки. Конечно, он должен быть добавлен как переменная окружения или конфигурационный файл, который не регистрируется в SVC.