如何让cancan授权gem限制用户只能使用自己拥有的数据?

发布于 2024-12-19 09:33:14 字数 2488 浏览 2 评论 0原文

您好,我实际上正在使用 Ryan' Bates cancan 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

controllers/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

但是在此之后,用户仍然可以操作另一个用户的数据。我缺少做什么。

Hello I'm actually using Ryan' Bates cancan gem authorization to make my application's users to only manage the data that they create.I'm using Sorcery gem to handle authentification.

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

controllers/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

But after this a user can still operate on another user's data.What am I missing to do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别在捏我脸啦 2024-12-26 09:33:15

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_resource 。 ,您可以单独使用 authorize_resourceload_resourse 更多详细信息此处

load_and_authorize_resource automatically provides you with @albums (so there is no need to set it again in index. So in the following:

def index
  @albums = Album.all
   .....# some code
end

@albums is being loaded again with all the albums, that's why it is showing them all. You can replace that with this:

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

But even this is not required as load_and_authorize_resource populates @albums with the correct albums for the current user. So the following would suffice:

def index
   .....# some code
end

will give you the same result. This is the power of cancan.Also, instead of load_and_authorize_resource, you can use authorize_resource or load_resourse separately. More details here

温折酒 2024-12-26 09:33:15

根据 文档,我相信您必须添加 load_and_authorize_resource 或类似于您想要授权的类,或者添加一个 authorize! 方法来手动处理控制器操作中的授权。

As per the documentation, i believe you have to add a load_and_authorize_resource or similar to your classes you want to authorize, or else add an authorize! method to manually handle authorization in a controller action.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文