Ruby on Rails
Autorisierung mit CanCan
Suche…
Einführung
CanCan ist eine einfache Berechtigungsstrategie für Rails, die von Benutzerrollen entkoppelt ist. Alle Berechtigungen werden an einem einzigen Ort gespeichert.
Bemerkungen
Bevor Sie CanCan verwenden, vergessen Sie nicht, Benutzer entweder nach einem erfundenen Juwel oder manuell zu erstellen. Um die maximale Funktionalität von CanCan zu erhalten, erstellen Sie einen Admin-Benutzer.
Erste Schritte mit CanCan
CanCan ist eine beliebte Berechtigungsbibliothek für Ruby on Rails, die den Benutzerzugriff auf bestimmte Ressourcen einschränkt. Das neueste Juwel (CanCanCan) ist eine Fortsetzung des toten Projekts CanCan .
Berechtigungen werden in der Ability
Klasse definiert und können von Controllern, Ansichten, Helfern oder anderen Stellen im Code verwendet werden.
Um einer App Autorisierungsunterstützung hinzuzufügen, fügen Sie der Gemfile den CanCanCan-Edelstein Gemfile
:
gem 'cancancan'
Dann definieren Sie die Fähigkeitsklasse:
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
end
end
Überprüfen Sie dann die Autorisierung mit load_and_authorize_resource
, um autorisierte Modelle in den Controller zu laden:
class ArticlesController < ApplicationController
load_and_authorize_resource
def show
# @article is already loaded and authorized
end
end
authorize!
um die Berechtigung zu prüfen oder eine Ausnahme zu erheben
def show
@article = Article.find(params[:id])
authorize! :read, @article
end
can?
um zu prüfen, ob ein Objekt gegen eine bestimmte Aktion in den Steuerungen, Ansichten oder Helfern autorisiert ist
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %>
<% end %>
Hinweis: Dies setzt voraus, dass der signierte Benutzer von der Methode current_user
bereitgestellt wird.
Fähigkeiten definieren
Fähigkeiten werden in der Ability
mit den Methoden can
und cannot
. Betrachten Sie das folgende kommentierte Beispiel als Basisreferenz:
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
Umgang mit einer großen Anzahl von Fähigkeiten
Sobald die Anzahl der Definitionen der Fähigkeiten zunimmt, wird es immer schwieriger, mit der Fähigkeitsdatei umzugehen.
Die erste Strategie, um mit diesem Problem umzugehen, besteht darin, Fähigkeiten in sinnvolle Methoden umzuwandeln, wie in diesem Beispiel gezeigt:
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
Sobald diese Klasse groß genug ist, können Sie versuchen, sie in verschiedene Klassen aufzuteilen, um die verschiedenen Verantwortlichkeiten wie folgt zu handhaben:
# 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
und definieren Sie dann diese Klassen als:
# app/models/abilities/guest.rb
module Abilities
class Guest
include CanCan::Ability
def initialize(user)
# Abilities for anonymous visitors only
end
end
end
und so weiter mit Abilities::Authenticated
, Abilities::Admin
oder einem anderen.
Testen Sie schnell eine Fähigkeit
Wenn Sie schnell testen möchten, ob eine Berechtigungsklasse die richtigen Berechtigungen erteilt, können Sie eine Fähigkeit in der Konsole oder in einem anderen Kontext mit geladener Schienenumgebung initialisieren.
test_ability = Ability.new(User.first)
test_ability.can?(:show, Post) #=> true
other_ability = Ability.new(RestrictedUser.first)
other_ability.cannot?(:show, Post) #=> true
Weitere Informationen: https://github.com/ryanb/cancan/wiki/Testing-Abilities