Я нашел довольно интересный способ преодолеть это, используя переменную сеанса, чтобы запомнить, какой пользователь вышел из системы. Идея состоит в том, что, хотя браузер все еще отправляет данные аутентификации, мы просто игнорируем их, потому что пользователь решил выйти из системы. Всякий раз, когда в браузер отправляется новый запрос на вход, все данные аутентификации стираются, поэтому пользователь может в любой момент вернуться в систему.
class ApplicationController < ActionController::Base
# ...
before_filter :authenticate
protected
def authenticate
authenticate_with_http_basic do |username, password|
@current_user = User.find_by_name_and_crypted_password(username, User.digest(password))
@current_user = nil if @current_user && session[:logged_out] == @current_user.id
!@current_user.nil?
end
end
def authenticate!
return if @current_user
session[:authenticate_uri] = request.request_uri
redirect_to('/login')
end
end
Затем на контроллере событий я делаю:
class EventsController < ApplicationController
before_filter :authenticate!, :only => [ :new, :create, :edit, :update ]
#...
end
И, наконец, мой контроллер сеанса выглядит так:
class SessionController < ApplicationController
before_filter :authenticate!, :only => [ :create ]
def create
if session[:authenticate_uri]
redirect_to(session[:authenticate_uri])
session[:authenticate_uri] = nil
else
redirect_to(new_event_path)
end
end
def destroy
session[:logged_out] = @current_user.id
redirect_to '/'
end
protected
def authenticate!
authenticate_or_request_with_http_basic("Rankings") do |username, password|
@current_user = User.find_by_name_and_crypted_password(username, User.digest(password))
if @current_user && session[:logged_out] == @current_user.id
@current_user = nil
session[:logged_out] = nil
end
!@current_user.nil?
end
end
end
И не забывайте свои маршруты!
map.logout 'login', :controller => 'session', :action => 'create'
map.logout 'logout', :controller => 'session', :action => 'destroy'