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条回答
可以哭但决不认输i
2楼-- · 2020-05-19 07:51

The simplest would be to to modify routes.rb.

Assign photos to live in the current_user path.

For example,

devise_for :users

resources 'users' do 
  resources 'photos'
end
查看更多
在下西门庆
3楼-- · 2020-05-19 07:52

If CanCan is too advanced, you should loon into checking the id of the accessor in the controller using...

if @user.id == @photo.user_id
  # edit photo details
else
  redirect_to root_path, notice: "You! Shall! Not! Edit!"

...or something like that

查看更多
甜甜的少女心
4楼-- · 2020-05-19 07:53

I captured the exception from within a before_filter action:

before_action :set_photo, only: [:edit, :update, :destroy]

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

  rescue ActiveRecord::RecordNotFound
    redirect_to(root_url, :notice => 'Record not found')
end

Hope this helps someone. I'm using Rails 4 and Ruby 2.

查看更多
乱世女痞
5楼-- · 2020-05-19 07:59

Check this railscasts,

http://railscasts.com/episodes/192-authorization-with-cancan

Complications you will run into,

  1. When you want cancan authorization on User Model that Devise gem is using for authentication

  2. When you want to store your Roles in the Database

  3. When you want to assign Permissions to the Roles as an Admin from the webUI

  4. and more ..

Please comment if you want any of those features, I will be happy to help, because I recently did them with great help from others and its always amazing to pass it on.

A sample Ability for your resources can be like as follows,

class Ability
  include CanCan::Ability

  def initialize(user)

      user ||= User.new # guest users
      send(user.role.name)

        if user.role.blank?
          can :read, User #for guest without roles
        end

  end

  def man
    can :manage, Photo
  end


  def boy
    can :read, Photo
  end

  def kid
    can :read, Article
  end

end
查看更多
成全新的幸福
6楼-- · 2020-05-19 08:02

In your PhotosController:

before_filter :require_permission, only: :edit

def require_permission
  if current_user != Photo.find(params[:id]).user
    redirect_to root_path
    #Or do something else here
  end
end
查看更多
等我变得足够好
7楼-- · 2020-05-19 08:03

cancan is difficult and complicate i have coding is_onwer method it's very simple, easy

https://gist.github.com/x1wins/0d3f0058270cef37b2d3f25a56a3745d

application controller

 def is_owner user_id
    unless user_id == current_user.id
      render json: nil, status: :forbidden
      return
    end
  end
  def is_owner_object data
    if data.nil? or data.user_id.nil?
      return render status: :not_found
    else
      is_owner data.user_id
    end
  end

your controller

  before_action only: [:edit, :update, :destroy] do
    is_owner_object @article ##your object
  end
查看更多
登录 后发表回答