Ich schreibe eine Rails-Anwendung für eine Organisation. Jeder Benutzer kann eine oder mehrere Rollen haben und kann abhängig von diesen Rollen nur auf bestimmte Controller-Aktionen zugreifen.
Beispielsweise können nur admins bestimmte Felder von User
s erstellen, löschen und aktualisieren. Außerdem gibt es Team
s, die jeweils einen team leader haben, und nur der team leader kann bestimmte Informationen über die Team
aktualisieren (wie beispielsweise die Mitgliederliste). Admins
ist jedoch derjenige, der den team leader an erster Stelle zuweist.
Die spezifischen Details meines Szenarios sind nicht wichtig. Ich hoffe nur, ich habe die Situation beschrieben, in der es viele verschiedene Rollen und Berechtigungen gibt.
Meine Frage ist: Welches Juwel soll ich verwenden? Mein erster Gedanke war CanCan, aber das letzte Commit war vor fast einem Jahr und die Kompatibilität mit Rails 4 wird nicht erwähnt. Gibt es eine aktuell gewartete Alternative?
Ihre erste Vermutung war richtig, verwenden Sie cancancan und Sie werden gut damit umgehen.
Ich habe cancancan schon lange benutzt und es hat immer gut funktioniert. Ich habe kürzlich den Job gewechselt, und hier benutzen wir Pundit zur Autorisierung.
Es ist toll. Sie werden aufgefordert, die Richtlinie für jede Ressource zu definieren, und es fühlt sich natürlicher an als eine aufgeblähte Fähigkeitsklasse.
Für größere Projekte würde ich Pundit auf jeden Fall empfehlen.
Um den Zugriff auf Aktionen zu steuern, empfehle ich Action Access , es läuft darauf hinaus:
class UsersController < ApplicationController
let :admin, :all
let :user, [:index, :show]
# ...
end
Dadurch wird der Controller automatisch gesperrt, sodass Administratoren auf jede Aktion zugreifen können, Benutzer nur Benutzer anzeigen oder indizieren können, und alle anderen Personen werden abgelehnt und mit einer Warnung umgeleitet.
Wenn Sie mehr Kontrolle benötigen, können Sie mit not_authorized!
in Aktionen den Zugriff prüfen und ablehnen.
Es ist vollständig unabhängig vom Authentifizierungssystem und kann ohne User
-Modelle oder vordefinierte Rollen arbeiten. Sie müssen lediglich den Freigabewert für die aktuelle Anfrage einstellen:
class ApplicationController < ActionController::Base
def current_clearance_level
session[:role] || :guest
end
end
Sie können hier alles zurückgeben, was Sie für Ihre App benötigen, beispielsweise current_user.role
.
Obwohl dies nicht erforderlich ist, werden eine Reihe praktischer Modellzusätze gebündelt, die folgende Funktionen ermöglichen:
<% if current_user.can? :edit, :team %>
<%= link_to 'Edit team', edit_team_path(@team) %>
<% end %>
Da :team
auf TeamsController
verweist, wird der Link nur angezeigt, wenn der aktuelle Benutzer zum Zugriff auf die edit
-Aktion in TeamsController
berechtigt ist. Es unterstützt auch namespaces.
Sie können Controller standardmäßig sperren, den Umleitungspfad und die Warnmeldung anpassen usw.
Es ist sehr unkompliziert und einfach, ich hoffe, Sie finden es nützlich.
Etwas, das mir vorgeschlagen wurde, das wir jetzt verwenden, ist das petergate gem. Einfach zu bedienen und sehr sauber mit einem großartigen Rails-Gefühl.
Funktioniert gut mit devise .
Hier einige Beispiele aus der Readme-Datei.
Wenn Sie mit devise arbeiten, haben Sie Glück, ansonsten müssen Sie Ihrem Projekt folgende Methoden hinzufügen:
user_signed_in?
current_user
after_sign_in_path_for(current_user)
authenticate_user!
Dies kommt in Ihrer User.rb. Das Hinzufügen weiterer Rollen ist so einfach wie das Hinzufügen zu einem Array.
petergate(roles: [:admin, :editor], multiple: false)
Instanzmethoden
user.role => :editor
user.roles => [:editor, :user]
user.roles=(v) #sets roles
user.available_roles => [:admin, :editor]
user.has_roles?(:admin, :editors) # returns true if user is any of roles passed in as params.
Controller-Zugriffssyntax.
access all: [:show, :index], user: {except: [:destroy]}, company_admin: :all