使用cancan和devise授权rails中的未登录用户行为

时间:2013-02-01 03:31:30

标签: ruby-on-rails authentication devise authorization cancan

Post: hidden: boolean

我希望登录用户可以看到所有帖子,而非登录用户只能访问隐藏字段为false的帖子。 所以我在cancan的能力模型中这样写:

if user_signed_in?
    can :read, Post
else 
    can :read, Post, :hidden => false
end

但在Model中不允许访问帮助程序user_signed_in。 正如这个问题所述:Rails 3 devise, current_user is not accessible in a Model ?。虽然我们可以使用一些技巧来访问帮助器,但它不适合这样做

那么,我怎样才能正确授权未登录用户?或者只是使用“Include”来使用这个助手?

或者我应该把它放在身份验证部分?但是如何?

1 个答案:

答案 0 :(得分:4)

您需要做的就是:

def initialize(user)
  user ||= User.new # guest user (not logged in)

  can :read, Post, :hidden => false

  if User.exists?(user)
    can :read, Post
  end
end

使用devise,current_user帮助器方法在登录时返回当前用户,但在未登录时返回nil。它在控制器和视图中可用。默认情况下,CanCan会针对current_user方法的返回执行所有授权检查。

现在,只要从视图或控制器调用can?方法,current_user的返回将作为局部变量{{1}传递给Ability的新实例。 }。

要检查用户是否已登录,我选择使用user。它是User.exists?()的类方法,用于检查数据库中是否持有ActiveRecord::Base个对象。任何其他方式都可以正常工作。例如,这可以同样好或更好:

user

这将检查if user.encrypted_password can :read, Post end 实例是否存在默认设计密码字段。如果你没有做过任何太疯狂的事情,那么只有在用户登录时才返回一个值。如果第二个选项适用于你的情况,它可能更好,因为你甚至不必查询数据库。

半相关提示,请查看像Rolify这样的角色处理宝石。与CanCan一起使用时非常棒。