Использование cancan для предотвращения доступа к контроллеру
У меня есть контроллер администратора, и я хочу, чтобы только пользователи, которые определены как admin, имели доступ к этому контроллеру.
мой класс способностей:
class Ability
include CanCan::Ability
def initialize(user)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
end
мой контроллер администратора:
class AdminController < ApplicationController
load_and_authorize_resource
def index
end
def users_list
end
end
когда я пытаюсь получить доступ к /admin/users_list
(либо с пользователем администратора, либо без него), я получаю следующую ошибку: uninitialized constant Admin
Что я делаю неправильно? Это правильный способ ограничить доступ к контроллеру?
Ответы
Ответ 1
Это связано с тем, что при использовании load_and_authorize_resource ваш контроллер должен быть подкреплен моделью с именем Admin (так как ваш контроллер называется AdminController). Таким образом, вам нужно либо создать эту модель, либо заменить load_and_authorize_resource на:
authorize_resource: class= > false
который вызывает проверку доступа к вашим действиям, а не к модели. Обратите внимание, что это, к сожалению, приводит к общим символам доступа, таким как : управлять и : читать, чтобы прекратить работу, требуя, чтобы вы перенаправляли действия контроллера непосредственно в способность .rb:
может [: index,: users_list],: admin
где первый аргумент представляет собой массив действий контроллера, к которому пользователь может получить доступ, а второй аргумент - краткое имя контроллера
Ответ 2
Вы можете ввести авторизацию в свой контроллер
authorize_resource :class => false
или
authorize_resource :class => :controller
Затем измените свое приложение/модели/файл Ability.rb
can :manage, :controller_name
См. this
Ответ 3
Отметьте это, чтобы добавить правила авторизации для не-restful-контроллеров:
https://github.com/ryanb/cancan/wiki/Non-RESTful-Controllers
Надеюсь, что это поможет.
Ответ 4
Это связано с тем, что когда вы создаете общий контроллер, поместите load_and_authorize_resource, тогда контроллер приложения или контроллер администратора не смогут найти фактический класс, из которого он пришел, как в этом примере. Это будет работать.
class Admin::HomeController < Admin::ApplicationController
def home
end
end
class Admin::ApplicationController < ApplicationController
load_and_authorize_resource :class => self.class
end
Ответ 5
У меня была такая же проблема. Моим решением было определение способности неспособности. Определено, что может сделать только администратор, я определяю, что не может сделать пользователь admin. В вашем коде будет что-то вроде этого:
Контроллер администратора:
class AdminController < ApplicationController
authorize_resource :class => AdminController
def index
end
def users_list
end
end
ability.rb:
class Ability
include CanCan::Ability
def initialize(user)
if user.admin?
can :manage, :all
else
can :read, :all
cannot [:index, :users_list], AdminController
end
end
end