Остановить настройку сеанса очистки
Кажется, что когда пользователь выходит из системы через стандартные Devise-контроллеры, Devise уничтожает все хранилище сеансов, а не только свои собственные данные. Есть ли способ избежать такого поведения? У меня есть другие нерелевантные данные, которые следует хранить.
session[:my_var] = "123"
Выйти из системы...
puts session[:my_var]
# => nil
Ответы
Ответ 1
Метод destroy
¹ SessionsController
содержит следующую строку:
signed_out = Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
Метод sign_out_all_scopes
² вызывает warden.logout
без каких-либо аргументов, а метод sign_out
³ вызывает warden.logout(scope)
.
В документации метода logout
⁴ указано:
# Logout everyone and clear the session
env['warden'].logout
# Logout the default user but leave the rest of the session alone
env['warden'].logout(:default)
Заключение: sign_out
должен сохранять сеанс при заданной конкретной области. Однако я не вижу никакого способа сделать это. sign_out_all_scopes
всегда вызывается первым и будет возвращать только false
, если он не сможет зарегистрировать пользователя.
Я рекомендую опубликовать запрос функции на своем трекер-проблеме или разработать собственное решение для проверки подлинности. Rails теперь предоставляет has_secure_password
, и в эти дни люди, кажется, собираются для последнего, чтобы избежать столкновения с этими проблемами.
¹ Devise::SessionsController#destroy
² Devise::Controllers::Helpers#sign_out_all_scopes
³ Devise::Controllers::Helpers#sign_out
⁴ Warden::Proxy#logout
Ответ 2
В последних версиях разработки нет необходимости переопределять контроллер сеансов, вместо этого вы можете просто использовать:
config.sign_out_all_scopes = false
В файле devise.rb
, чтобы получить желаемое поведение.
Ответ 3
Вы можете просто переопределить Devise SessionController, как я сделал, чтобы сохранить корзину:
sessions_controller.rb
class SessionsController < Devise::SessionsController
def destroy
order_id = session[:order_id]
super
session[:order_id] = order_id
end
end
routes.rb
devise_for :users, :controllers => { :sessions => "sessions" }
Ответ 4
В дополнение к Маттею. Утверждение
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
- это, пожалуй, лучший общий вывод, учитывая возможность входа в систему с несколькими ролями. Если для вас случай, ваш пользователь только что подписал в качестве одной роли, и вы хотите сохранить остальную часть сессии на выводе, самый простой способ сделать:
$ git clone git://github.com/plataformatec/devise.git
$ cd devise
$ git branch my_devise
$ git checkout my_devise
Откройте приложение/контроллеры/devise/sessions_controller.rb в своем редакторе. В методе destroy замените
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
с
signed_out = sign_out(resource_name)
Сохранить и выйти из редактора и сделать
$ git commit -am "remove only warden data from session on logout, preserve other data."
В Gemfile вашего проекта описать зависимость, которую вы можете использовать, например
gem 'devise', :path => "[YOUR PATH]/devise", :branch => "my_devise"