[英]Authorizing non-logged-in user behavior in rails with cancan and devise
Post: hidden: boolean
I want the logged in user could see all the posts, and the non-logged-in user only have access to posts whose hidden fields are false. 我希望已登录的用户可以看到所有帖子,而未登录的用户只能访问其隐藏字段为false的帖子。 So I write like this in cancan's Ability Model:
所以我在坎康的能力模型中这样写:
if user_signed_in?
can :read, Post
else
can :read, Post, :hidden => false
end
but accessing the helper user_signed_in is not allowed in Model. 但是在Model中不允许访问助手user_signed_in。 As stated in this question: Rails 3 devise, current_user is not accessible in a Model ?
如这个问题所述: Rails 3设计,在模型中不能访问current_user? .
。 While we could using some tricks to access the helper, its not proper to do that
尽管我们可以使用一些技巧来访问帮助程序,但这样做不合适
So, how could I authorize the not-logged-in user properly? 那么,如何正确授权未登录的用户? Or just use "Include" to use this helper ??
或者只是使用“包含”来使用此帮助程序?
Or should I put this in authentication part? 还是应该将其放入身份验证部分? but how?
但是如何?
All you need to do is this: 您需要做的就是:
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
With devise, the current_user
helper method returns the current user when logged in but returns nil when not logged in. It is available in the controllers and views. 通过devise,
current_user
帮助程序方法在登录时返回当前用户,但在未登录时返回nil。在控制器和视图中可用。 By default, CanCan does all authorization checks against the return of the current_user
method. 默认情况下,CanCan会针对
current_user
方法的返回执行所有授权检查。
Now whenever the can?
现在何时
can?
method is called from a view or a controller, the return of current_user
will be passed to a new instance of Ability
as the local variable user
. 方法是从一个视图或控制器调用,返回
current_user
将被传递到的一个新实例Ability
作为本地变量user
。
To check if the user was logged in, I choose to use User.exists?()
. 要检查用户是否已登录,我选择使用
User.exists?()
。 It's a class method for ActiveRecord::Base
that will check if that user
object is persisted in the database. 这是
ActiveRecord::Base
的类方法,它将检查该user
对象是否保留在数据库中。 Any other way will work just as well though. 任何其他方式都将同样有效。 For instance, this would work just as well or better:
例如,这将同样或更好地工作:
if user.encrypted_password
can :read, Post
end
This will check if the default devise password field exists for the user
instance. 这将检查
user
实例的默认设备密码字段是否存在。 If you haven't done anything too crazy, this will only return a value if the user is logged in. If the second option works for your situation, it may be superior because you won't even have to query the database. 如果您还没有做任何疯狂的事情,那么只有在用户登录后,它才会返回一个值。如果第二个选项适合您的情况,那么它可能会更好,因为您甚至不必查询数据库。
Semi-relevant tip, check out a role handling gem like Rolify . 半相关提示,请查看处理Rolify之类的角色 。 It is great when used in conjunction with CanCan.
与CanCan结合使用时效果很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.