Ruby on Rails
Autorisation avec CanCan
Recherche…
Introduction
CanCan est une stratégie d'autorisation simple pour Rails qui est découplée des rôles d'utilisateur. Toutes les autorisations sont stockées dans un seul emplacement.
Remarques
Avant d’utiliser CanCan, n’oubliez pas de créer des utilisateurs soit par gem, soit manuellement. Pour obtenir un maximum de fonctionnalités de CanCan, créez un utilisateur Admin.
Commencer avec CanCan
CanCan est une bibliothèque d'autorisation populaire pour Ruby on Rails qui restreint l'accès des utilisateurs à des ressources spécifiques. Le dernier bijou (CanCanCan) est une continuation du projet mort CanCan .
Les autorisations sont définies dans la classe Ability
et peuvent être utilisées à partir de contrôleurs, de vues, de helpers ou de tout autre endroit du code.
Pour ajouter un support d'autorisation à une application, ajoutez le joyau CanCanCan au Gemfile
:
gem 'cancancan'
Ensuite, définissez la classe de capacité:
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
end
end
Ensuite, vérifiez l'autorisation à l'aide de load_and_authorize_resource
pour charger les modèles autorisés dans le contrôleur:
class ArticlesController < ApplicationController
load_and_authorize_resource
def show
# @article is already loaded and authorized
end
end
authorize!
vérifier l'autorisation ou lever une exception
def show
@article = Article.find(params[:id])
authorize! :read, @article
end
can?
vérifier si un objet est autorisé par rapport à une action particulière dans les contrôleurs, les vues ou les assistants
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %>
<% end %>
Remarque: Cela suppose que l'utilisateur signé est fourni par la méthode current_user
.
Définir les capacités
Les capacités sont définies dans la classe Ability
utilisant les méthodes can
et cannot
. Considérez l'exemple ci-dessous pour la référence de base:
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
Gérer un grand nombre de capacités
Une fois que le nombre de définitions de capacités commence à augmenter, il devient de plus en plus difficile de gérer le fichier Ability.
La première stratégie pour gérer ces problèmes consiste à déplacer des capacités dans des méthodes significatives, comme dans cet exemple:
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
Une fois que cette classe est devenue suffisamment importante, vous pouvez essayer de la diviser en différentes classes pour gérer les différentes responsabilités comme ceci:
# 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
et définissez ensuite ces classes comme suit:
# app/models/abilities/guest.rb
module Abilities
class Guest
include CanCan::Ability
def initialize(user)
# Abilities for anonymous visitors only
end
end
end
et ainsi de suite avec des Abilities::Authenticated
, Abilities::Admin
ou tout autre.
Testez rapidement une capacité
Si vous souhaitez tester rapidement si une classe de capacité donne les autorisations correctes, vous pouvez initialiser une capacité dans la console ou dans un autre contexte avec l'environnement des rails chargé, il suffit de passer une instance d'utilisateur à tester:
test_ability = Ability.new(User.first)
test_ability.can?(:show, Post) #=> true
other_ability = Ability.new(RestrictedUser.first)
other_ability.cannot?(:show, Post) #=> true
Plus d'informations: https://github.com/ryanb/cancan/wiki/Testing-Abilities