Check if current_user is the owner of a resource a

2020-05-19 07:38发布

Example:

User A (id=10) has created a photo resource

photo: (id: 1 user_id = 10, url: "http://...")

Now, if User B (id=20) go to this url: /photos/1/edit it can edit photo of user A!!!

Rails+Devise provides something for this by default? It seems it's a very common issue

I just need to allow that any user can edit/delete ONLY resource it has created (where current_user == resource.user)

Using: Rails 4, Devise

Update:

I think CanCan it's something too advanced. I don't need roles or restrict some actions to certain users

9条回答
▲ chillily
2楼-- · 2020-05-19 08:04

Write another before_filter in application_controller:

before_filter :has_permission?

has_permission?
controllers=["articles", "photos", "..."]
actions=["edit", "destroy", "..."]
id = params[:id] if (controllers.include?(params[:controller] && actions.include?(params[:action]) end
if id && (current_user.id==(params[:controller][0...1].capitalize!+params[:controller].singularize[1...-1] + ".find(#{id}).user_id").send)
return true
else
redirect_to root_url, :notice=>"no permission for this action"
end

helper_method :has_permission?

And you can use it in views, not to show users link they can't follow.

Some kind of this, of course you need to modify it to suit your needs.

查看更多
时光不老,我们不散
3楼-- · 2020-05-19 08:06

So you are using gem devise.

This gem provides the current_user for the currently logged in user.

In your PhotosController#edit method. I'd do something like below.

def edit
  @photo = Photo.find(params[:id])
  redirect_to root_path, notice: 'Thou Shalt Nought duuu dat :(' unless current_user.id == @photo.user_id
  ...
end

This method is cheaper because you already have 2 objects to compare instead of running a query in the comparison.

查看更多
我命由我不由天
4楼-- · 2020-05-19 08:08

You can make use of Rails' associations and write it like this:

def edit
  @photo = current_user.photos.find(params[:id])

  # ... do everything else
end

This will only find a record when the photo with the supplied ID belongs to the current user. If it doesn't, Rails will raise a ActiveRecord::RecordNotFound exception.

Of course, I'm assuming the current_user method is available and your User model contains the statement has_many :photos.

查看更多
登录 后发表回答