Какова цель Ролифи?

Привет, я использую rolify и только что понял, что на самом деле я не использую весь его потенциал.

В настоящее время я делаю что-то в своем контроллере, например, перенаправляю пользователей, если current_user.has_role? :whatever_role, и разрешаю пользователям, если у них есть какая-либо другая роль...

Кто-то задал вопрос на stackoverflow о rolify, и когда я попытался ответить на него, я понял, что делаю это неправильно.

Вот тут-то и начинается мое замешательство... Внутри Ability.rb у меня есть:

user ||= User.new # guest user (not logged in)
if user.has_role? :consumer
  can :manage, Review
else
  can :read, Review
end

Теперь предположим, что я добавляю пользователю роль потребителя:

x=User.last
x.add_role :consumer
# => #<Role id: 10, name: "consumer", resource_id: nil, resource_type: nil, created_at: "2013-04-18 23:00:46", updated_at: "2013-04-18 23:00:46"> 

Итак, роль создана. Я могу проверить это, выполнив:

x.has_role? :consumer
=> true

Теперь я ожидаю, что это даст возможность управления для обзоров ...

x.has_role? :consumer, Review
=> true

но не для других моделей... здесь я пробую продукты

x.has_role? :consumer, Product
=> true

Кроме того, когда я смотрю на «запрос ролей ресурсов» и пытаюсь запросить прикладные роли для отзывов, я не нахожу прикладных ролей:

Review.first.applied_roles
=> []

Может кто-нибудь, пожалуйста, объясните мне роль ролифы. Спасибо


person Chris Keele    schedule 19.04.2013    source источник
comment
Мне нравится Reddit как источник вопросов, но мне нравится, что stackoverflow является авторитетным источником ответов. Поэтому я воспроизвел вопрос, который всем может показаться проще и быстрее; и опубликовал мой ответ на Reddit. Если мой ответ не будет воспринят им как положительный на Reddit, я свяжусь с любым лучшим ответом в ответе здесь, а затем закрою это. В противном случае, я бы хотел, чтобы здесь тоже был дан ответ на его вопрос, который я затем передам на Reddit.   -  person Chris Keele    schedule 19.04.2013


Ответы (1)


Мой ответ, дополненный вопросом из этот пост на Reddit:

Аутентификация — это установление User того, за кого себя выдают.

Авторизация — это установление того, что User может выполнять заданное действие, будь то чтение или запись, после того, как они установили свою личность.

Роли – это просто распространенные шаблоны авторизации для пользователей: эта User может быть авторизована как таковая, а User может быть авторизована в таком виде .

Здесь вам не хватает компонента Разрешения: отношения между установленным Role и некоторым действием контроллера.

Roles сами не дают никаких обещаний о том, какие действия User может выполнить. И помните: авторизация — это действия. Roles обобщите, с каким User вы имеете дело. Они существуют для того, чтобы вам не приходилось запрашивать у каждого User гигантский список Permissions. Они заявляют: этот User есть Role! Конечно, у них есть Permission для этого!

Есть много типов Permission. Вы можете сохранить их в базе данных, если хотите, чтобы ваши авторизованные Users могли их редактировать, а также ваши Roles, если они тоже должны быть настраиваемыми. Или, если ваши User's Roles достаточно статичны, вы можете заранее управлять Permissions с помощью кода Ruby:

  • Когда я хочу иметь настраиваемые Roles и Permissions, то есть для клиентского приложения, которое вы передаете кому-то по завершении контракта, я реализую User :has_many Roles и Role :has_many Permissions со своими собственными моделями, а затем добавляю хук before_filter :authorize в свою ApplicationController, и напишите для него метод authorize, который знает, как бороться с этими ожиданиями, или создайте страницу 403 для тех людей, которые настаивают на ручном вводе URL-адресов вещей, которые, как они надеются, откроют actions вещи, к которым у них не должно быть доступа.

  • Когда мне нужно просто настроить Roles, я использую жемчуг CanCan Райана Бейтса.

  • Когда я хочу заранее определить Roles и Permissions, я использую Rolify в сочетании с Nathan Long's Authority, чтобы получить восхитительно гибкий Permissions на основе классов с помощью классов Authorizer.

И Roles, и Permissions могут быть основаны либо на классе, либо на экземпляре, в зависимости от вашего варианта использования. Вы можете, скажем, с помощью способностей rolify, которые вы только что открыли, решить, что Users может действовать как Role только в определенных обстоятельствах, основанных на экземплярах. Или общие Roles из User могут выполнять действие только при условии, что объект, над которым они пытаются действовать, относится к определенному типу.

Чтобы изучить их перестановку, предполагая приложение для блога, следуя формуле

User кто Role class/instance может action а/все/любой/тот (class/instance) Permission:

  • Role класс и Permission класс:

    User, который является Admin, может delete любой Post.

  • Класс Role и экземпляр Permission:

    User, которому Admin, может edit все Posts that they approved to be published

    Это было бы проще, если бы в опубликованных сообщениях было поле approved_by, указывающее на идентификатор User. (Используйте конечный автомат жемчужина для подобных ситуаций.

  • Экземпляр Role и класс Permission:

    User, которому an Author of a Post, может comment на любом Post

    Обратите внимание, что такого рода ситуации случаются редко, поэтому нет упомянутых выше драгоценных камней для обработки этой ситуации, за исключением, возможно, возможности управлять предопределенными обстоятельствами, такими как Rolify и Authority в сочетании; или, если вы должны передать это решение своему клиенту, ваше собственное индивидуальное решение.

  • экземпляр Role и экземпляр Permission:

    User, которому an Author of a Post, может edit того Post.

TL;DR:

  • Rolify предназначен только для ролей: группировка Users по Permission: доступ к действию контроллера. Вам еще предстоит решить, как вы собираетесь управлять Permissions.

Надеюсь, это поможет вам понять положение Rolify в общей схеме аутентификации и авторизации!

person Chris Keele    schedule 19.04.2013
comment
Итак, если Rolify предназначен только для ролей — какой смысл его использовать? Я использую Devise + CanCanCan и определяю вручную в user.rb def admin? admin end затем в Ability.rb: if user.admin? can :manage, :all else can :read, :all - person prograils; 12.01.2017
comment
@prograils Это зависит от того, как вы хотите написать свой код авторизации (Devise в основном просто аутентификация). CanCanCan — это библиотека разрешений, которая хорошо сочетается с Rolify. Вы должны спросить себя, откуда взялся метод user.admin?. Сначала это мог быть просто логический атрибут пользователя. По мере того, как вы перерастаете в небинарную ролевую систему, вы в конечном итоге получите массу логических флагов в модели. Если у пользователя может быть много ролей, ваши проверки могут быстро усложниться. Rolify позволила бы этому стать user.has_role? :admin и аккуратно справиться с растущей сложностью. - person Chris Keele; 12.01.2017
comment
@prograils Rolify также позволяет более детально определять роли. Вы можете добавить роли для пользователей для конкретных экземпляров ресурсов. Например, вы хотите, чтобы пользователь «Джо» имел роль «менеджер проекта», но только для проекта «XYZ». ссылка - person Tom; 18.01.2018