Chr*_*ier 9 authentication ruby-on-rails ruby-on-rails-plugins
我在rails应用程序中安装了restful_authentication插件,其session_controller具有如下所示的destroy方法:
def destroy
self.current_user.forget_me if logged_in?
cookies.delete :auth_token
reset_session
flash[:notice] = "You have been logged out."
redirect_back_or_default('/')
end
Run Code Online (Sandbox Code Playgroud)
在应用程序控制器中我有:
before_filter :login_required
Run Code Online (Sandbox Code Playgroud)
在sessions_controller我有:
skip_before_filter :login_required
Run Code Online (Sandbox Code Playgroud)
我的问题是,当用户使用http基本身份验证进行身份验证时,他/她不会注销.会话被销毁,但用户可以毫无问题地导航到受限制的页面.通过插件进行会话身份验证不会发生此问题.如何使这种方法摆脱基本的认证?
Chr*_*ier 13
服务器端无法在这种情况下"注销"用户.当用户通过基本身份验证登录时,浏览器会存储身份验证信息,并在每次请求时通过http标头发送身份验证参数.如果用户使用基本身份验证登录,他/她将必须关闭他/她的浏览器窗口才能注销.
我发现了一种非常有趣的方法来克服这个问题,即使用会话变量来记住哪个用户已注销。这个想法是,即使浏览器仍在发送身份验证数据,我们也只是忽略它,因为用户选择了注销。每当新的登录请求发送到浏览器时,所有身份验证数据都会被删除,因此用户可以随时重新登录。
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
Run Code Online (Sandbox Code Playgroud)
然后,在事件控制器上我执行以下操作:
class EventsController < ApplicationController
before_filter :authenticate!, :only => [ :new, :create, :edit, :update ]
#...
end
Run Code Online (Sandbox Code Playgroud)
最后我的会话控制器如下所示:
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
Run Code Online (Sandbox Code Playgroud)
并且不要忘记您的路线!
map.logout 'login', :controller => 'session', :action => 'create'
map.logout 'logout', :controller => 'session', :action => 'destroy'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13502 次 |
| 最近记录: |