检查current_user是否是资源的所有者并允许编辑/删除操作
例:
用户A (id = 10)已创建照片资源
photo: (id: 1 user_id = 10, url: "http://...")
现在,如果用户B (id = 20)转到此url: /photos/1/edit
它可以编辑用户A的照片!!!
Rails + Devise默认为此提供了一些东西? 这似乎是一个非常普遍的问题
我只需要允许任何用户只能编辑/删除它创建的资源(其中current_user == resource.user)
使用: Rails 4,设计
更新:
我想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
exception。
当然,我假设current_user
方法可用,而您的User
模型包含语句has_many :photos
。
检查这个railscast,
http://railscasts.com/episodes/192-authorization-with-cancan
你会遇到的并发症,
-
如果您想在Devise gem用于身份validation的用户模型上进行cancan授权
-
当您想要将角色存储在数据库中时
-
如果要从WebUI将权限分配给角色作为管理员
-
和更多 ..
如果您想要任何这些function,请评论,我将很乐意提供帮助,因为我最近在其他人的帮助下做了这些,并且总是让人难以理解。
您的资源的示例能力可以如下所示,
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操作中捕获了exception:
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
此方法更便宜,因为您已经有2个对象要比较,而不是在比较中运行查询。
最简单的方法是修改routes.rb。
将照片分配到current_user路径中。
例如,
devise_for :users resources 'users' do resources 'photos' 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?
您可以在视图中使用它,而不是向用户显示他们无法关注的链接。
某种,当然你需要修改它以满足你的需要。