我希望能够根据Authlogic的登录/退出状态在routes.rb
中设置根URL。以下是我需要做的一个例子:
root :to => 'users#index', :constraints => lambda { |request| # ??? }
root :to => 'welcome#index'
get '/' => 'users#index', :as => 'user_root'
这将使登录用户能够转到users#index
并注销用户,无需进行重定向即可转到welcome#index
。我知道如何设置一个before_filter并相应地重定向,但我宁愿不这样做。
答案 0 :(得分:1)
您可以非常轻松地创建自定义路径约束。响应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
被定义为实例方法并创建实例变量 - 如果它们没有为每个请求分开,您将不确定用户是否实际登录或另一个人之前登录过。
如果Authlogic尝试直接访问params
,可能会遇到问题。在这种情况下,您可能需要覆盖UserSession.new
方法以接受request
对象作为参数,并调用request.params
来获取参数。
答案 1 :(得分:1)
Authlogic已经拥有本地机器(已针对Rails 6.0和Authlogic 6.0进行了测试):
class AuthlogicSignedInConstraint
def matches?(request)
Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::AbstractAdapter.new(request)
user_session = UserSession.find
user_session && user_session.user
end
end
答案 2 :(得分:0)
最新版本的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 authenticate_with_http_basic
end
def cookies
request.cookies
end
def params
request.params
end
def session
_, session_hash = Rails.application.config.session_store.new(Rails.application, Rails.application.config.session_options).load_session(request.env)
session_hash
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