Rails - 安全地更新用户信息

时间:2013-05-25 01:42:37

标签: ruby-on-rails login

在许多书籍和教程中,我看到人们在用户控制器中实现update方法,要么通过params [:id]或session [:id]查找用户数据。但是,我觉得可以简单地修改会话或地址栏以侵入别人的帐户并修改他/她的信息。因此,如何确保用户只能更新自己的信息而不是更改其他信息。

4 个答案:

答案 0 :(得分:0)

答案是针对特定应用的。您需要先“找到”记录 - 其中有关如何查找该记录的详细信息取决于应用程序。

是的,正如您所指出的,您不应该盲目地实例化记录并更新它。在将其公开以进行更新之前,您的业务逻辑需要智能地找到相关记录。

答案 1 :(得分:0)

将用户模型视为与任何其他模型相同,并将您的身份验证添加到其中,并要求用户在uddate方法中登录(例如,某些auth方法的current_user)。

if current_user
  update_stuff and redirect
else
  :notice => 'Not authd' and redirect
end 

答案 2 :(得分:0)

在处理需要私有的应用程序时,我曾经遇到过这个问题。我所做的是使用DeviseCancan以及优秀的rails实践。我使用Devise进行身份验证,cancan用于授权。

在某些情况下,您可以使用hidden_​​field在表单中传递用户ID。我建议在控制器创建操作中传递user_id,并且在使用设计时,您可以访问current_user方法,该方法仅根据当前用户会话和id创建模型。

使用cancan保护用户信息。例如,如果我只能在没有用户2看到照片的情况下向用户显示这样的照片。

@photos = current_user.photos #only grabs current users photos

使用cancan我可以阻止用户手动输入像users / 2 / edit这样的网址来做这样的事情

<强> Ability.rb

can :manage, Photo, :user_id => user.id

<强> controller.rb

load_and_authorize_resource :photo

def index
  authorize! :index, @photo
end

答案 3 :(得分:0)

我实际上围绕这个主题进行了相当多的应用程序构建/研究,所以我将尝试给出详细的答案。

以同样的方式,您可以在非用户,登录用户和管理员帐户之间划分应用程序或网站的各个部分,您可以实施检查以确保,例如,只有正确的用户才能更改其帐户密码。以下是您可能用于此类方法的测试:

describe "as wrong user" do
  let(:user) { FactoryGirl.create(:user) }
  let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
  before { sign_in user, no_capybara: true }

  describe "submitting a GET request to the Users#edit action" do
    before { get edit_user_path(wrong_user) }
    specify { expect(response.body).not_to match(full_title('Edit user')) }
    specify { expect(response).to redirect_to(root_url) }
  end

  describe "submitting a PATCH request to the Users#update action" do
    before { patch user_path(wrong_user) }
    specify { expect(response).to redirect_to(root_url) }
  end
 end
end

如果您不熟悉测试(或不确定具体做什么),我将解释:

在代码中,工厂可以选择(下面的这一特定行)

FactoryGirl.create(:user, email: "wrong@example.com")

这基本上创建了一个具有默认电子邮件地址的用户。然后,所有发生的事情都是测试指定错误的用户不应该有权访问原始用户的编辑或更新操作。

下一步是添加一个before过滤器来检查当前用户的状态。这可能会出现在users_controller.rb文件中。

before_action :correct_user,   only: [:edit, :update]

然后(仍然在users_controller.tb文件中)创建一个私有方法来检查当前用户是否有权修改数据,否则将它们重定向回根网址(如果你看中你可以使用[:notice]说“你无权访问这部分应用程序”或类似的东西)

private
def correct_user
  @user = User.find(params[:id])
  redirect_to(root_url) unless current_user?(@user)
end

correct_user过滤器使用您在Sessions帮助程序中定义的current_user?布尔方法,如下所示:

def current_user
remember_token = User.encrypt(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end

def current_user?(user)
user == current_user
end

对于谁可以访问的内容而言,这并不是安全的全部教条,但我希望它能为您提供问题中提到的缺失细节。