我希望能够根据Authlogic的登录/注销状态在routes.rb
中设置根网址。这是我需要做的一个例子:
root :to => 'users#index', :constraints => lambda { |request| # ??? }
root :to => 'welcome#index'
get '/' => 'users#index', :as => 'user_root'
这将使登录用户可以转到users#index
,而注销用户可以转到welcome#index
无进行重定向。我确实知道如何设置一个before_filter并进行相应的重定向,但是我宁愿不这样做。
您可以非常轻松地创建自定义路线约束。任何响应matches?
的对象都可以交给:constraints
路由选项。要检查Authlogic身份验证,您需要从ApplicationController中提取Authlogic方法并将其放在其他位置。无论如何,我建议您关注这些问题。
# app/concerns/authlogic_methods.rb
module AuthlogicHelpers
extend ActiveSupport::Concern
module InstanceMethods
private # All methods are private
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.user
end
end
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include AuthlogicHelpers
end
# config/initializers/route_constraints.rb
module RouteConstraints
class LoggedIn
include AuthlogicHelpers
def matches?(request)
current_user
end
end
end
# config/routes.rb
constraints RouteConstraints::LoggedIn.new do
root :to => 'dashboard#show'
end
请注意,我们正在实例化一个新的RouteConstraints::LoggedIn
对象。这是因为Authlogic方法current_user
和current_user_session
被定义为实例方法并创建实例变量-如果未针对每个请求将它们分开,则您将无法确定用户是否已实际登录或已登录另一个用户在之前。
params
,则您可能会遇到问题。在这种情况下,您可能需要重写UserSession.new
方法以接受request
对象作为参数,然后调用request.params
以获取参数。
最新版本中的Authlogic需要实例化一个控制器对象,否则它将找不到加载会话所需的会话数据。
实际上,在authlogic/controller_adapters/
下包含的是用于各种控制器实现的适配器:Rails控制器,Sinatra和Rack。
接口非常简单,所以我写了一个适配器来处理在约束内可以访问的ActionDispatch::Request
。
这已经在Rails 4.2上进行了测试,Rails 5应该相似。
class AuthlogicRequestAdapter
attr_reader :request
def initialize(request)
@request = request
end
def cookies
request.cookies
end
def params
request.params
end
def session
Rails.application.config.session_store.load_session(request.env)
end
end
路线约束
class UserRouteConstraint
def matches?(request)
Authlogic::Session::Base.controller = AuthlogicRequestAdapter.new(request)
user = UserSession.find
if user&.record.present?
true
else
false
end
end
end
routes.rb
MyRailsApp::Application.routes.draw do
# ... other routes
constraints(UserRouteContraint.new) do
root :to => 'users#index'
end
root :to => 'welcome#index'
get '/' => 'users#index', :as => 'user_root'
end