在使用Devise的开源Rails应用程序中,我无法允许匿名用户读取资源。似乎Devise / Warden参与其中并且在CanCan可能参与之前抛弃拒绝逻辑。
我只需要匿名用户拥有对文档和注释模型的列表和读取权限。
我从authenticated :user
代码块中删除了一些路由,以防止Devise立即拒绝。
# config/routes.rb
resources :documents
# moved to here
get 'annotations', to: 'annotations#index'
get 'annotations/:id', to: 'annotations#show'
...
authenticated :user do
...
# moved from here
#get 'annotations', to: 'annotations#index'
#get 'annotations/:id', to: 'annotations#show'
...
end
我实现了一个基于Devise Community's recommendation的访客用户,虽然我使用了多态而不是创建一个全新的函数,并找出了我需要把它放在旧代码中的所有地方。当然,我还修改了create_guest_user
方法,以便为我们的系统实际创建一个有效的访客用户。
# app/controllers/application.rb
def current_user
if super
if session[:guest_user_id]
guest_user.destroy
session[:guest_user_id] = nil
end
super
else
guest_user
end
end
helper_method :current_user
# find guest_user object associated with the current session,
# creating one as needed
def guest_user
begin
# Cache the value the first time it's gotten.
@cached_guest_user ||= User.find(session[:guest_user_id] ||= create_guest_user.id)
#sign_in(:user, @cached_guest_user)
rescue ActiveRecord::RecordNotFound # if session[:guest_user_id] invalid
session[:guest_user_id] = nil
guest_user
end
end
...
def create_guest_user
u = User.create(:firstname => "guest", :lastname => "user", :email => "guest_#{Time.now.to_i}#{rand(99)}@example.com")
u.save!(:validate => false)
session[:guest_user_id] = u.id
# establish guest user credentials
u.set_roles = ['guest']
u.rep_group_list << 'public'
u.save!(:validate => false)
u
end
有了这个,匿名用户开始体验到登录页面的重定向循环。有了经过验证的猜测和检查方法,我想出了这个:
# allow guest user to be generated prior to authentication
def authenticate_user!
current_user
super
end
使用所有预期设置创建访客用户,这些设置已通过控制台和数据库确认。匿名/访客用户可以成功导航到登录页面,登录,注销,一旦通过身份验证,一切正常。
但是,如果访客用户尝试列出注释,则会将用户重定向到sign_in页面,其中包含401 Unauthenticated和一条闪烁消息,其中显示&#34;您需要在继续之前登录或注册。&#34;如果访客用户尝试列出文档或查看文档,则会出现相同的结果。
我删除了Document控制器上的before_filter :authenticate_user!
作为测试,这似乎有助于周围的情况。然而,在没有使用它的情况下,几乎没有在Devise周围走动?
我是否应该放弃尝试让Devise将访客用户视为足够认证,以便将决定权移交给CanCan?我希望Devise能够处理身份验证,但我并不希望它能够使用401 bat击败未经验证的人。
是否可以从匿名访问的控制器方法中删除:authenticate_user!
?我从Devise自述文件中得到了:authenticate_user!
过滤器激活Devise功能的印象。我开始怀疑它只是陛下的看门人,这些陛下超越了有围墙的认证天堂。
我认为看门人通过routes.rb
阻止在authenticated :user
。 before_filter :authenticate_user!
中的authenticated :user
和routes.rb
块之间有什么区别?两者似乎都对401响应有点沉重,似乎都阻止访客用户访问资源。
相关的SO问题和设计社区页面已经帮助但未解决问题:
我有a GitHub ticket背景,我试图在这里简明扼要地总结一下。 The original code在GitHub上可用,my current progress也是如此。