Rails中是否有授权gem来处理以下内容:
我有一位想要更新自己个人资料的用户。他们会调用HTTP POST到http://example/users/:user_id/profile.xml
之类的东西。问题是,很多处理代码的代码如下:
if params[:user_id] == current_user.id
# allow update!
else
# don't allow update
什么授权gem允许抽象出来,这样具体来说,逻辑可以自动隐含,而不必在每个需要它的方法中手动检查它?
答案 0 :(得分:0)
首先,你不需要宝石,你将不得不编写自己的代码。
逻辑可以自动隐含,而不必检查它 在需要它的每种方法中手动?
这就是before_filters所做的。您很可能已经在application_controller.rb中设置了一个。前置过滤器将确保在每个需要它的操作之前调用authorize方法 请参阅此处unde section 7过滤器以获取更多详细信息 http://guides.rubyonrails.org/action_controller_overview.html
最后,我希望您不要暗示更新配置文件的xml帖子请求不应该登录!他们肯定应该,http基本身份验证将为您处理。
见这里 http://api.rubyonrails.org/classes/ActiveResource/Base.html
也适用于Rails => v 3.1 http://railscasts.com/episodes/270-authentication-in-rails-3-1
<强>更新强>
从下面的评论中可以清楚地看出,我所提供的建议如何帮助解决您的问题并不明显
以下是您如何使用上述信息。 应用程序控制器中的前置过滤器将确保当前用户正常,因此您无需检查控制器参数是否为==当前用户用户ID的用户ID。
其次,如果您想知道是否允许用户执行特定操作,则将方法添加到用户类。
之类的东西def can_do_something?
#Put your code here to check if something is allowed for this specific user
end
然后代替
if params[:user_id] == current_user.id
# allow update!
else
# don't allow update
您要对要更新的模型添加验证(可能以某种方式与用户相关),然后在授权和身份验证检查之上根本不需要额外的控制器代码来处理此问题或者如果是不太合适,你真的必须把代码放在你的控制器然后这样做
if current_user.can_do_something?
# allow update!
else
# don't allow update
答案 1 :(得分:0)
您的问题涉及两个部分:
在这种情况下,身份验证基本上是允许用户登录和注册您的网站的概念。你没有在你的问题中提到这一点,所以也许你已经实现了它。如果你还没有,我建议你研究一下Devise (here),它真的很容易使用,但也非常强大。
授权是您询问的具体内容。也就是说,一旦用户登录,这对他有什么特权,而不是用户。此外,管理员还有哪些额外的权限等等。像我之前提到的其他人一样,最好的方法是使用CanCan (here)。
我在我做过的第一个rails应用程序中使用了这两个,它们非常易于使用。
此外,如果您不想像CanCan那样需要如此广泛的授权解决方案,您只需使用before_filter
并将重复的代码放在那里。我在另一个应用程序中使用了这种方法,这篇文章将帮助你:(here)
答案 2 :(得分:0)
您的基本案例将通过以这种方式简单地找到资源来处理:
def update
# Best practice: only look for resources that belong to this user
@post = User.posts.find(params[:id])
...
end
如果您需要额外的检查,我的Authority gem会让您感觉非常轻松。您可以通过在Authorizer类上编写updatable_by?
等方法并让模型将这些问题委托给授权者来定义谁可以对资源做什么。这样,具有相同规则的模型可以使用相同的授权者。
在你的控制器中,你会得到一些不错的便利方法:
class FoosController < ApplicationController
# Sets up some before_filter checks at the class level. In other words,
# if the user can never update any instance of Foo, they'll never even reach
# the update method
authorize_actions_for Foo
...
# Before this ever runs, we'll have asked if any Foo is ever `updatable_by?`
# the current user; if not, they'll see your "access denied" page.
def update
# If they got this far, they can at least update **some** Foo instances
# (though maybe not this one)
@foo = current_user.foos.find(params[:id]) # this alone handles ownership check
# Now that we know the specific instance, we can ask whether **this** Foo is
# `updatable_by?` the user. This shorthand method checks with the authorizer and
# shows the "access denied" page if the answer is false.
authorize_action_for(@foo)
...
end
end
由于您只是在授权者上编写纯Ruby方法,因此您可以检查您知道如何检查Ruby的任何内容。
def updatable_by?(user)
resource.community_owned? && user.points > 20 || user.has_role?(:moderator)
end
有关详细信息,请参阅detailed README。