如何使cancan授权gem限制用户使用他们拥有的数据?

时间:2011-12-05 15:24:52

标签: ruby-on-rails authorization cancan

您好我实际上正在使用Ryan'Bates cancan gem授权,使我的应用程序的用户只管理他们创建的数据。我正在使用Sorcery gem来处理身份验证。

models / ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
       user ||= User.new # guest user (not logged in)
       if user
        can :manage, Profile, :user_id => user.id
        can :manage, Album, :user_id => user.id
       end

  end
end

控制器/ albums_controllers.rb

# -*- encoding : utf-8 -*-
class AlbumsController < ApplicationController

    # Authentification before accessing Albums
    before_filter :require_login, :except => [:not_authenticated]
    load_and_authorize_resource


  def index
    @albums = Album.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @albums }
    end
  end


  def show
    @album = Client.find(params[:id])
    authorize! :show, @album

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @album }
    end
  end


  def new
    @album = Album.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @album }
    end
  end

  def edit
    @album = Album.find(params[:id])
     authorize! :edit, @album
  end


  def create
    @album = Album.new(params[:album])

    respond_to do |format|
      if @album.save
        format.html { redirect_to @album, notice: 'album was successfully created.' }
        format.json { render json: @album, status: :created, location: @album }
      else
        format.html { render action: "new" }
        format.json { render json: @album.errors, status: :unprocessable_entity }
      end
    end
  end


  def update
    @album = Album.find(params[:id])
     authorize! :update, @album

    respond_to do |format|
      if @album.update_attributes(params[:album])
        format.html { redirect_to @album, notice: 'Album was successfully updated.' }
        format.json { head :ok }
      else
        format.html { render action: "edit" }
        format.json { render json: @album.errors, status: :unprocessable_entity }
      end
    end
  end


  def destroy
    @album = Album.find(params[:id])
    @album.destroy

    respond_to do |format|
      format.html { redirect_to albums_url }
      format.json { head :ok }
    end
  end
end

但在此之后,用户仍然可以操作其他用户的数据。我不想做什么。

2 个答案:

答案 0 :(得分:5)

load_and_authorize_resource会自动为您提供@albums(因此无需在index中再次设置它。所以在以下内容中:

def index
  @albums = Album.all
   .....# some code
end
正在使用所有相册再次加载

@albums,这就是为什么它会全部显示。您可以将其替换为:

def index
  @albums = Album.accessible_by(current_ability)
   .....# some code
end

但即使这不是必需的,因为load_and_authorize_resource使用当前用户的正确相册填充@albums。所以以下就足够了:

def index
   .....# some code
end

会给你相同的结果。这是cancan的力量。而且,您可以单独使用load_and_authorize_resourceauthorize_resource,而不是load_resourse。更多详情here

答案 1 :(得分:2)

根据documentation,我认为您必须为要授权的类添加load_and_authorize_resource或类似内容,或者添加authorize!方法以手动处理授权控制器动作。