我的app中有restful_authentication。随之而来的是会话控制器。除了一件事,一切都在为我工作。当窗口关闭然后在同一台机器上重新打开时,将保存应用程序状态,包括登录用户。我需要我的应用程序在浏览器窗口关闭时将用户注销。但我不知道如何实现它。是否存在导致其保存的东西,或者我是否需要添加一些东西来杀死它?
这是会话控制器:
# This controller handles the login/logout function of the site.
class SessionsController < ApplicationController
# render new.rhtml
def new
end
def create
logout_keeping_session!
user = User.authenticate(params[:login], params[:password])
if user
unless user.active?
# ensures "deleted" users can't login
user = nil
end
end
if user
# Protects against session fixation attacks, causes request forgery
# protection if user resubmits an earlier form using back
# button. Uncomment if you understand the tradeoffs.
# reset_session
self.current_user = user
new_cookie_flag = (params[:remember_me] == "1")
handle_remember_cookie! new_cookie_flag
redirect_back_or_default('/')
else
note_failed_signin
@login = params[:login]
@remember_me = params[:remember_me]
render :action => 'new'
end
end
def destroy
logout_killing_session!
redirect_back_or_default('/', :notice => "You have been logged out.")
end
protected
# Track failed login attempts
def note_failed_signin
flash.now[:alert] = "Couldn't log you in as '#{params[:login]}'"
logger.warn "Failed login for '#{params[:login]}' from #{request.remote_ip} at #{Time.now.utc}"
end
end
以下是authenticatedSystem模块(显然不相关的材料已移除)
module AuthenticatedSystem
protected
# Returns true or false if the user is logged in.
# Preloads @current_user with the user model if they're logged in.
def logged_in?
!!current_user
end
# Accesses the current user from the session.
# Future calls avoid the database because nil is not equal to false.
def current_user
@current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
end
# Store the given user id in the session.
def current_user=(new_user)
session[:user_id] = new_user ? new_user.id : nil
@current_user = new_user || false
end
def authorized?(action = action_name, resource = nil)
logged_in?
end
def login_required
authorized? || access_denied
end
def access_denied
respond_to do |format|
format.html do
store_location
redirect_to new_session_path
end
# format.any doesn't work in rails version < http://dev.rubyonrails.org/changeset/8987
# Add any other API formats here. (Some browsers, notably IE6, send Accept: */* and trigger
# the 'format.any' block incorrectly. See http://bit.ly/ie6_borken or http://bit.ly/ie6_borken2
# for a workaround.)
format.any(:json, :xml) do
request_http_basic_authentication 'Web Password'
end
end
end
# Store the URI of the current request in the session.
#
# We can return to this location by calling #redirect_back_or_default.
def store_location
session[:return_to] = request.fullpath
end
# Redirect to the URI stored by the most recent store_location call or
# to the passed default. Set an appropriately modified
# after_filter :store_location, :only => [:index, :new, :show, :edit]
# for any controller you want to be bounce-backable.
def redirect_back_or_default(default, options = {})
redirect_to((session[:return_to] || default), options)
session[:return_to] = nil
end
# Inclusion hook to make #current_user and #logged_in?
# available as ActionView helper methods.
def self.included(base)
base.send :helper_method, :current_user, :logged_in?, :authorized? if base.respond_to? :helper_method
end
#
# Login
#
# Called from #current_user. First attempt to login by the user id stored in the session.
def login_from_session
self.current_user = User.find_by_id(session[:user_id]) if session[:user_id]
end
# Called from #current_user. Now, attempt to login by basic authentication information.
def login_from_basic_auth
authenticate_with_http_basic do |login, password|
self.current_user = User.authenticate(login, password)
end
end
#
# Logout
#
# Called from #current_user. Finaly, attempt to login by an expiring token in the cookie.
# for the paranoid: we _should_ be storing user_token = hash(cookie_token, request IP)
def login_from_cookie
user = cookies[:auth_token] && User.find_by_remember_token(cookies[:auth_token])
if user && user.remember_token?
self.current_user = user
handle_remember_cookie! false # freshen cookie token (keeping date)
self.current_user
end
end
# This is ususally what you want; resetting the session willy-nilly wreaks
# havoc with forgery protection, and is only strictly necessary on login.
# However, **all session state variables should be unset here**.
def logout_keeping_session!
# Kill server-side auth cookie
@current_user.forget_me if @current_user.is_a? User
# @current_user = false # not logged in, and don't do it for me
kill_remember_cookie! # Kill client-side auth cookie
session[:user_id] = nil # keeps the session but kill our variable
# explicitly kill any other session variables you set
end
# The session should only be reset at the tail end of a form POST --
# otherwise the request forgery protection fails. It's only really necessary
# when you cross quarantine (logged-out to logged-in).
def logout_killing_session!
logout_keeping_session!
reset_session
end
答案 0 :(得分:3)
当您的浏览器(在我的情况下为Firefox)启动首选项设置为“从上次显示我的窗口和标签页”时,会发生这种情况。当关闭浏览器(所有窗口)时,“下次启动时保存选项卡”也会发生这种情况。在这些情况下,浏览器会记住sesssion,即它不会像通常那样删除会话cookie。
答案 1 :(得分:1)
当用户重新打开浏览器时,您将通过cookie对其进行身份验证。尝试从
中删除login_from_cookie
def current_user
@current_user ||= (login_from_session || login_from_basic_auth) unless @current_user == false
end