在Rails中,如何验证用户是否有权修改条目?

时间:2013-05-10 02:54:28

标签: ruby-on-rails ruby devise ruby-on-rails-3.2

在我的rails应用程序中,我正在使用Devise来验证应用程序中的用户。它为我提供了current_user.id这样的变量,它是当前登录用户的UserID。

在我的应用中,每个用户都是至少一个群组的成员。任何用户都可以创建一个或多个小饰品,并可以将每个小饰品分配给其中一个小组。

所以,这是我的模特:

User has_many :memberships
User has_many :groups, :through => :memberships

Group has_many :memberships
Group has_many :users, :through => :memberships
Group has_many :trinkets

Trinket belongs_to :group

所以有我的模特!一切都很好!

当用户更新Trinket时,他们可以将该Trinket分配给其中一个组。

但是,存在安全漏洞!如果有人查看了Trinket / edit或Trinket / new页面,请复制HTML源代码,更改表单中<SELECT><INPUT>标记的值,他们实际上可以将其Trinket提交给其他人的GroupID

我想在模型或控制器中添加验证,以确认用户在将数据写入数据库之前确实可以使用提交的值。在这种情况下,我想查看此Trinket的GroupID是否是User.find(current_user.id).groups内的GroupID,但我无法弄清楚如何在Trinket模型中进行验证。

任何人都知道如何验证用户是否正在尝试为实际有权分配值的内容分配值? Devise或其他gem是否有办法检查用户提交的数据的关联?

目前的Trinket模型文件只有:

attr_accessible :trinketname, :group_id
validates_presence_of :trinketname

希望这是有道理的。感谢帮助! : - )

版本:Rails 3.2.13,Ruby 1.9.3p392,Devise 2.2.4。我的application_controller.rb文件中有protect_from_forgery

2 个答案:

答案 0 :(得分:1)

您可以在操作中添加if语句。这可能不准确但我希望它能解决这个问题:

 def create
   if trinket.group_id == current_user.group_id
     trinket.new(params[:trinket])
       if trinket.save
         redirect_to somewhere
       else 
         render :new
       end
   else      
    flash[:warn] "You're not allowed"
 end

答案 1 :(得分:1)

您需要的是授权。

考虑使用众多可用授权框架中的一个来实现您的目标。

Ryan Bates的CanCan是最受战争考验的人之一。

更新:Ability可以执行:

class Ability
  include CanCan::Ability

  def initialize(user)
    can :manage, Trinket, group: { id: user.group_ids }
  end
end