Rails 3 限制访问,以便用户只能更新他们的数据

发布于 2024-12-03 05:33:19 字数 410 浏览 5 评论 0原文

这看起来应该是相当简单的事情,因为它会被很多需要。我检查用户是否正常登录,但一旦用户登录,他们可能会更改其他人的帐户。例如:假设 ID 为 1 的用户已登录,并且他们将 /users/2/edit 作为 url。这将向他们显示用户 2 的数据并允许他们修改它。当然,我可以更改控制器中的编辑操作以使用类似这样的操作...

  def edit
    @user = User.find(current_user.id)
  end

其中 current_user 在控制器中设置,因此用户始终是登录的人。如果您只有几个带有几个动作,但如果你有很多动作,可能会很痛苦。似乎应该有一种方法可以在全球范围内限制这种情况,以便用户无论使用什么操作或控制器都只能更新自己的数据。

有没有办法限制用户只能使用自己的数据进行所有操作?

This seems like something that should be fairly simple since it would be needed a lot. I check to see if a user is logged in fine but once a user is logged in they could potentially alter other peoples accounts. For example: say user with ID 1 was logged in and they put /users/2/edit as the url. This would show them user 2s data and allow them to modify it. Of course I can alter the edit action in the controller to use something like this...

  def edit
    @user = User.find(current_user.id)
  end

where current_user is set in the controller so the user is always that person who is logged in. This is fine if you only have a couple controllers with a couple actions but could be a pain if you have many. It seems like there should be a way to limit this globally so the user can only update their own data no matter what action or controller they use.

Is there a way to restrict the user to their own data for all actions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

潜移默化 2024-12-10 05:33:19

在您的 application_controller.rb 中,您可以尝试以下操作:

class ApplicationController < ActionController::Base
  before_filter :validate_user

  private

  def validate_user() #might need to pass id and current_user
    if current_user.id == params[:id]
      # continue to current_user url
    else
        flash[:error] = "Please access one of your own pages"
        redirect_to(:back)
    end
  end
end

通过将内容放入应用程序控制器中,它应该在所有控制器中可用,但是如果您不需要确认这是当前用户(例如主页),那么您可以需要在任何需要它的特定控制器(针对特定操作)中使用skip_before_filter,例如在页面控制器中使用skip_before_filter

class PagesController < ApplicationController
  skip_before_filter :validate_user, :only => [:home, :about]
end

。 href="http://guides.rubyonrails.org/action_controller_overview.html#filters" rel="nofollow">过滤器上的 Rails 指南链接。也可能有更有效的方法来实现这一目标。

希望有帮助

In your application_controller.rb you can try this:

class ApplicationController < ActionController::Base
  before_filter :validate_user

  private

  def validate_user() #might need to pass id and current_user
    if current_user.id == params[:id]
      # continue to current_user url
    else
        flash[:error] = "Please access one of your own pages"
        redirect_to(:back)
    end
  end
end

by putting the stuff in the application controller it should be available in all the controllers, however if you do not need to confirm that this is the current user (say maybe home page) then you may need to use a skip_before_filter in any specific controller(for a specific action) that needs it, like this in the pages controller for example

class PagesController < ApplicationController
  skip_before_filter :validate_user, :only => [:home, :about]
end

For more info checkout this link to rails guides on filters. There could be more efficient ways of achieving this as well.

Hope it helps

爺獨霸怡葒院 2024-12-10 05:33:19

我认为你的问题实际上是关于如何进行授权。另外,我怀疑您可能会将“belongs_to”模型关联名称与授权混为一谈。 “belongs_to”关联名称描述了一个模型如何与另一个模型相关,但它并不暗示应用程序如何控制对任何模型的访问。

Hishalv 是正确的,使用控制器过滤器是管理授权的正确方法。这是正确的 MVC 方式。仔细阅读 Rails 指南,以便您理解这一点。

然后,您可以考虑使用像 CanCan 这样的授权 gem,或者根据 Hishalv 的建议推出您自己的 gem。 CanCan 与像 Devise 这样的身份验证 gem 配合使用效果很好。如果您确实要自己开发,那么在 ApplicationController 中放置一个辅助方法并以无论模型如何都可以工作的方式编写它是一件简单的事情。

I think your question is really about how to do authorization. Also, I suspect you might be conflating the "belongs_to" model association name with authorization. The "belongs_to" association name describes how one model relates to another, but it does not imply anything about how an application controls access to any model.

Hishalv is correct that using a controller filter is the right way to manage authorization. It's the correct MVC way. Give the Rails Guide a good read so you understand that.

Then, you can consider using an authorization gem like CanCan, or rolling your own per Hishalv's suggestion. CanCan works well in tandem with an authentication gem like Devise. If you do roll your own, it's a simple thing to put a helper method in ApplicationController and write it in such a way that it works regardless of the model.

土豪 2024-12-10 05:33:19

我一直觉得有点奇怪的是,当最终用户只想更新自己的帐户时,他们却暴露在 Rails“内部”中,例如 /users/2/edit。

所以我更喜欢调用它的方法

resource :account

而不是

resources :users

然后你有像 /account/account/edit 等路径,并且只需要处理登录用户的数据。

I have always found it a bit strange that end users were exposed to Rails "internals" such as /users/2/edit when all they wanted to do was update their own account.

So I prefer the method of calling it

resource :account

instead of

resources :users

Then you have paths like /account, /account/edit and so on, and need only handle data for the logged in user.

云巢 2024-12-10 05:33:19

如果你使用cancan然后

def validate_user
 unless current_user.id == params[:id].to_i
  raise CanCan::AccessDenied
 end
end

在application_controller中写

   rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = "Access denied."
    redirect_to access_denied_path
  end

If you are using cancan then

def validate_user
 unless current_user.id == params[:id].to_i
  raise CanCan::AccessDenied
 end
end

And in application_controller write

   rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = "Access denied."
    redirect_to access_denied_path
  end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文