5

我一直在阅读有关 Rails 安全问题的信息,而让我最担心的是批量分配。我的应用程序正在使用 attr_accessible,但是我不确定我是否完全知道处理暴露关系的最佳方法是什么。假设我们有一个基本的内容创建/所有权网站。用户可以创建博客文章,并拥有一个与该博客文章相关联的类别。

所以我有三个模型:

  • 用户
  • post:属于一个用户和一个类别
  • 类别:属于用户

我允许对 category_id 进行批量分配,因此用户可以将其取消,将其更改为他们的类别之一,或者通过批量分配,我想他们可以将其更改为其他人的类别。这就是我有点不确定最好的方法是什么。

我调查的资源(特别是railscast #178和从该 railscast 提供的资源)都提到关联不应该是可批量分配的,这是有道理的。我只是不确定如何让用户以一种随意的方式更改帖子的类别。

关于如何最好地解决这个问题的任何想法?我看错了吗?

更新:希望能进一步澄清我的担忧。

假设我在 Post,我是否需要以下内容:

def create
  @post = Post.new(params[:category])

  @post.user_id = current_user.id

  # CHECK HERE IF REQUESTED CATEGORY_ID IS OWNED BY USER

  # continue on as normal here
end

这似乎是很多工作?我需要在更新和创建操作中检查每个控制器。请记住,不仅仅是一个 belongs_to 关系。

4

2 回答 2

5

我想你的用户可以通过某种编辑形式来改变它。

基于此,Mass Assignment 真的适用于那些试图通过 curl 之类的东西弄乱你的应用程序的邪恶类型。我称他们为卷曲小子。

说了这么多,如果你使用attr_protected- (在这里你放了你不希望他们改变的字段)或孩子最喜欢的attr_accessible(可以改变的字段)。

您会听到两者的论据,但如果您attr_protected :user_id在模型中使用,然后在 CategoryController#create 操作中,您可以执行类似的操作

def create
  @category = Category.new(params[:category])

  @category.user_id = current_user.id
  respond_to do |format|
....#continue on as normal here
end
于 2010-01-29T02:51:35.877 回答
0

好的,所以搜索了一下,最后想出了一些对我有用的东西。我喜欢尽可能将逻辑排除在控制器之外,因此此解决方案是基于模型的解决方案:

# Post.rb
validates_each :asset_category_id do |record, attr, value|
  self.validates_associated_permission(record, attr, value)
end

# This can obviously be put in a base class/utility class of some sort.
def self.validates_associated_permission(record, attr, value)
  return if value.blank?
  class_string = attr.to_s.gsub(/_id$/, '')
  klass = class_string.camelize.constantize

  # Check here that the associated record is the users
  # I'm leaving this part as pseudo code as everyone's auth code is
  # unique.
  if klass.find_by_id(value).can_write(current_user)
    record.errors.add attr, 'cannot be found.'
  end
end

我还发现 rails 3.0 将有更好的方法来指定它,而不是超通用 validates_each 所需的 3 行。

http://ryandaigle.com/articles/2009/8/11/what-s-new-in-edge-rails-independent-model-validators

于 2010-01-29T19:43:25.377 回答