检查current_user是否是资源的所有者,并允许编辑/删除操作



示例:

用户A(id=10)创建了照片资源

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

现在,如果用户B(id=20)转到这个url:/photos/1/edit,它可以编辑用户A的照片!!!

Rails+Devise默认情况下为此提供了什么?似乎是一个很常见的问题

我只需要允许任何用户都可以编辑/删除它创建的ONLY资源(其中current_user==resource.user)

使用:Rails 4,Devise

更新:

我觉得CanCan太高级了。我不需要角色,也不需要将某些操作限制为特定用户

在您的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

您可以利用Rails的关联并像这样编写:

def edit
  @photo = current_user.photos.find(params[:id])
  # ... do everything else
end

只有当提供ID的照片属于当前用户时,才会找到记录。如果没有,Rails将引发一个ActiveRecord::RecordNotFound异常。

当然,我假设current_user方法是可用的,并且您的User模型包含语句has_many :photos

检查此轨道支架,

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

,您将遇到的并发症

  1. 当你想取消Devise gem用于身份验证的用户模型的授权时

  2. 当您想将您的角色存储在数据库中时

  3. 当您想从webUI 以管理员身份为角色分配权限时

  4. 等等。。

如果你想要这些功能中的任何一个,请发表评论,我很乐意提供帮助,因为我最近在其他人的大力帮助下完成了这些功能,并且它总是令人惊叹的。

您的资源的示例能力可以如下所示,

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

我从before_filter操作中捕获了异常:

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

希望这能帮助到别人。我使用的是Rails 4和Ruby 2。

所以您使用的是gem devise

此gem为当前登录的用户提供current_user

在您的PhotosController#edit方法中。我会做下面这样的事情。

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

这种方法比较便宜,因为您已经有两个对象要比较,而不是在比较中运行查询。

最简单的方法是修改routes.rb.

将照片分配到current_user路径中。

例如,

devise_for :users
resources 'users' do 
  resources 'photos'
end

cancan既困难又复杂我有编码is_onwer的方法它非常简单,容易

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

应用控制器

 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

您的控制器

  before_action only: [:edit, :update, :destroy] do
    is_owner_object @article ##your object
  end

如果CanCan太高级,您应该使用…检查控制器中访问器的id。。。

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

或者类似的东西

在application_controller:中编写另一个before_filter

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?

你可以在视图中使用它,而不是向用户显示他们无法关注的链接。

某种类型的,当然你需要修改它以满足你的需求。

相关内容

  • 没有找到相关文章

最新更新