2011-04-27 47 views
3

我已经设置了Devise来管理我的应用程序的身份验证。设计和当前用户

我有一个类别模型,其中用户创建自己的类别。用户has_many:类别。此模型具有user_id属性,因此,当某人登录并转到类别/索引时,查询会使用current_user.id将类别过滤掉要带入的类别。

到目前为止,并且运作良好,似乎没有人能够看到别人的类别,但说实话,除非我错过了某些东西,这似乎有点不安全。我怎么知道一些黑客不知道并发送他自己的请求修改params?

这是可能或我是偏执​​?另外,我可能没有正确使用功能?

+0

我不确定我是否确切知道你在哪些类别中引入。这是在控制器?视图?假设您在用户has_many:categories中使用关系,则可以使用current_user.categories和current_user.categories.build(在您的控制器中)。如果您可以举例说明您的代码在哪里以及它的使用方式,那么这可能会让我们对安全性有更好的了解。它实际上听起来像是在视图内而不是控制器中为当前用户过滤,这对我来说似乎是一个坏主意。 – 2011-04-27 14:18:11

+0

编辑问题以解决您的意见。过滤确实发生在控制器上。有没有办法,以这种方式完成你可能会看到其他人的信息? – Lievcin 2011-04-27 14:30:12

回答

1

我认为你有一个对一个(每个用户一个类别)的关系设置,而不是一个一对多(每用户许多类别)。如果User型号中有category_id,则应该进行以下设置。

# in User.rb 
belongs_to :category 

# in Category.rb 
has_many :users 

# in CategoriesController 
@category = current_user.category 

如果你想有每个用户的多个类别,比我建议使用一个链接表(如模型UserCategory)与user_idcategory_id

# in UserCategory.rb 
belongs_to :user 
belongs_to :category 

# in User.rb 
has_many :user_categories 
has_many :categories, :through => :user_categories 

# in Category.rb 
has_many :user_categories 
has_many :users, :through => :user_categories 

然后,在你Category控制器,你可以用你的代码从上面给定用户抓住所有类别。

# in CategoriesController.rb 
@categories = current_user.categories 
2

只要你正在使用userscategories之间的正确关系,即

# in User.rb 
has_many :categories 

# in Category.rb 
belongs_to :user 

,你应该能够使用这样的事情在你的控制器:

@categories = current_user.categories 

这样你使用当前用户,而不管可以传递哪些参数,并且只会获得他们的画廊。您不再通过可能不安全的user_id进行搜索。

如果您担心某人能够查看不属于他们的类别,您可以添加自己的类似于:authenticate_user!的私有方法,以确保显示或编辑的类别实际上属于当前用户,在另一个before_filter中运行它,如果它们没有权限,则重定向。

private 
    def authenticate_owner! 
    if user_signed_in? && current_user.id == params[:id] # or something similar 
     return true 
    end 
    redirect_to root_url, 
     :notice => "You must have permission to access this category." 
    return false 
    end 
+0

感谢您的建议。这不会阻止类别被列在我首先想到的位置。你觉得我的恐惧没有根据吗? (如果我没有在设计上实现我自己的方法) – Lievcin 2011-04-27 14:42:32

+0

这取决于你想要访问哪些类别。这些可以应用于您的任何控制器操作。如果您只希望查看者查看自己的类别,我会将current_user.categories用于您的索引或任何其他视图。我包含的方法仅适用于我想要基于身份的访问权限的内容,例如个人照片库的show操作。 – 2011-04-27 14:52:30

+0

我个人不太了解会议如何在Devise中工作,也不足以说明您的代码如何工作(或者应该保护什么),以告诉您您的恐惧是否完全没有根据。但是Devise只能让用户能够登录并且拥有身份的用户会话,并且可以基于登录来限制访问。使用它,您必须实现自己的方法,以在用户登录后进一步限制访问。(根据我的经验,至少) – 2011-04-27 14:55:36

0

根据乔希的回答,我只是把它变成了if else语句。我将params[:id]转换为整数,因为current_user.id返回1。

class UsersController < ApplicationController 
    before_filter :authenticate_owner! 
    #.... 
    private 
    def authenticate_owner! 
    if user_signed_in? && current_user.id == params[:id].to_i 
     return 
    else 
     redirect_to root_url, :notice => "You must have permission to access this page." 
    end 
    end 
end