私はdevise
とcancan
gems を使用し、モデルの関連付けは単純です: user
has_many subscriptions
, subscription
belongs_to :user
. 以下を持っていますSubscriptionsController
:
class SubscriptionsController < ApplicationController
load_and_authorize_resource :user
load_and_authorize_resource :subscription, through: :user
before_filter :authenticate_user!
def index
@subscriptions = @user.subscriptions.paginate(:page => params[:page]).order(:created_at)
end
#other actions
end
そしてCancan
Ability.rb
:
class Ability
include CanCan::Ability
def initialize(user)
user ||=User.new
can [:read], [Edition, Kind]
if user.admin?
can :manage, :all
elsif user.id
can [:read, :create, :destroy, :pay], Subscription, user_id: user.id
can [:delete_from_cart, :add_to_cart, :cart], User, id: user.id
end
end
end
問題は、subscriptions
アクションをユーザーとして使用できないが、管理者として使用できることです。そして、問題はありませんUsersController
。から次の行を削除するとSubscriptionsController
:
load_and_authorize_resource :user
load_and_authorize_resource :subscription, through: :user
before_filter :authenticate_user!
まったく問題ありません。したがって、これらの行またはの問題Ability.rb
。助言がありますか?
更新:can? :index, Subscription
HTML テンプレートにsmth like を追加すると、それが表示されるのは興味深いことですtrue
。can? :index, Subscription.first
(別のユーザーのサブスクリプション)のように追加すると、 が表示されますfalse
。Cancan
正常に動作しているように見えます。しかし、何が問題なのですか?...
UPDATE : 次のように変更した場合SubscriptionsControlle
:
class SubscriptionsController < ApplicationController
#load_and_authorize_resource :user
#load_and_authorize_resource :subscription, through: :user
before_filter :authenticate_user!
def show
@user = User.find params[:user_id] #line 1
@subscription = @user.subscriptions.find params[:id] #line 2
@container_items = @subscription.container_items.paginate(:page => params[:page])
authorize! :show, @subscription #line 4
end
#some actions
end
完璧に機能し、必要に応じて不正なユーザー アクセスを防ぎます。1行目、2行目、4行目はコメントと同等ではありませんか?..
更新: に次のものがありますroutes.rb
。
resources :users, except: [:show] do
member do
get 'cart'
delete 'delete_from_cart' => 'users#delete_from_cart'
post 'add_to_cart' => 'users#add_to_cart'
end
resources :subscriptions do
member do
post 'pay'
end
end
end
更新: 次の解決策は、次を除くすべてのサブスクリプション アクションへの不正アクセスを防止しますindex
。
class SubscriptionsController < ApplicationController
load_resource :user
load_resource :subscription, through: :user
authorize_resource through: :current_user
before_filter :authenticate_user!
#actions
end
index
では、アクションへのアクセスを防ぐ最善の方法は何でしょうか?
次の解決策のみが見つかりました:
before_filter :authorize_index, only: [:index]
def authorize_index
raise CanCan::AccessDenied unless params[:user_id] == current_user.id.to_s
end