匿名用户收到401 Unauthorized /必须使用Rails 3,Devise进行回复

时间:2014-05-16 19:02:00

标签: ruby-on-rails devise anonymous

在使用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

上下文中的代码为herehere

有了这个,匿名用户开始体验到登录页面的重定向循环。有了经过验证的猜测和检查方法,我想出了这个:

    # 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 :userbefore_filter :authenticate_user!中的authenticated :userroutes.rb块之间有什么区别?两者似乎都对401响应有点沉重,似乎都阻止访客用户访问资源。

相关

相关的SO问题和设计社区页面已经帮助但未解决问题:

背景

我有a GitHub ticket背景,我试图在这里简明扼要地总结一下。 The original code在GitHub上可用,my current progress也是如此。

0 个答案:

没有答案