Ruby on Rails
Авторизация с помощью CanCan
Поиск…
Вступление
CanCan - это простая стратегия авторизации для Rails, которая отделена от пользовательских ролей. Все разрешения хранятся в одном месте.
замечания
Перед тем, как использовать CanCan, не забудьте создать Пользователей, создав драгоценный камень или вручную. Чтобы получить максимальную функциональность CanCan, создайте пользователя Admin.
Начало работы с CanCan
CanCan - популярная библиотека авторизации для Ruby on Rails, которая ограничивает доступ пользователей к определенным ресурсам. Последний камень (CanCanCan) является продолжением мертвого проекта CanCan .
Разрешения определяются в классе « Ability
» и могут использоваться из контроллеров, представлений, помощников или любого другого места в коде.
Чтобы добавить поддержку авторизации в приложение, добавьте камень Gemfile
в Gemfile
:
gem 'cancancan'
Затем определите класс способности:
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
end
end
Затем проверьте авторизацию с помощью load_and_authorize_resource
для загрузки разрешенных моделей в контроллер:
class ArticlesController < ApplicationController
load_and_authorize_resource
def show
# @article is already loaded and authorized
end
end
authorize!
проверить авторизацию или создать исключение
def show
@article = Article.find(params[:id])
authorize! :read, @article
end
can?
чтобы проверить, разрешен ли объект для конкретного действия в любом месте контроллеров, представлений или помощников
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %>
<% end %>
Примечание. Предполагается, что подписанный пользователь предоставлен методом current_user
.
Определение способностей
Способности определяются в классе Ability
используя методы can
и cannot
. Рассмотрим следующий приведенный ниже пример базовой ссылки:
class Ability
include CanCan::Ability
def initialize(user)
# for any visitor or user
can :read, Article
if user
if user.admin?
# admins can do any action on any model or action
can :manage, :all
else
# regular users can read all content
can :read, :all
# and edit, update and destroy their own user only
can [:edit, :destroy], User, id: user_id
# but cannot read hidden articles
cannot :read, Article, hidden: true
end
else
# only unlogged visitors can visit a sign_up page:
can :read, :sign_up
end
end
end
Обработка большого количества способностей
Как только число определений способностей начинает расти в количестве, становится все труднее обрабатывать файл способности.
Первой стратегией для решения этой проблемы является перемещение способностей в осмысленные методы, как в этом примере:
class Ability
include CanCan::Ability
def initialize(user)
anyone_abilities
if user
if user.admin?
admin_abilities
else
authenticated_abilities
end
else
guest_abilities
end
end
private
def anyone_abilities
# define abilities for everyone, both logged users and visitors
end
def guest_abilities
# define abilities for visitors only
end
def authenticated_abilities
# define abilities for logged users only
end
def admin_abilities
# define abilities for admins only
end
end
Как только этот класс станет достаточно большим, вы можете попробовать разбить его на разные классы, чтобы справиться с различными обязанностями:
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
self.merge Abilities::Everyone.new(user)
if user
if user.admin?
self.merge Abilities::Admin.new(user)
else
self.merge Abilities::Authenticated.new(user)
end
else
self.merge Abilities::Guest.new(user)
end
end
end
а затем определите эти классы как:
# app/models/abilities/guest.rb
module Abilities
class Guest
include CanCan::Ability
def initialize(user)
# Abilities for anonymous visitors only
end
end
end
и т. д. с возможностями Abilities::Authenticated
, Abilities::Admin
или любым другим.
Быстро проверить способность
Если вы хотите быстро протестировать, если класс способности дает правильные разрешения, вы можете инициализировать возможность в консоли или в другом контексте с загруженной средой рельсов, просто передайте экземпляр пользователя для проверки на:
test_ability = Ability.new(User.first)
test_ability.can?(:show, Post) #=> true
other_ability = Ability.new(RestrictedUser.first)
other_ability.cannot?(:show, Post) #=> true
Дополнительная информация: https://github.com/ryanb/cancan/wiki/Testing-Abilities