Binden Sie je nach Benutzerrollen eine Route an verschiedene Controller

8

In meiner Symfony 2 App habe ich 3 verschiedene Benutzerrollen, die Zugriff auf einen Backend-Verwaltungsteil haben können:

%Vor%

Für eine Route wie http://example.org/admin/post/ möchte ich, dass meine App abhängig von der Benutzerrolle unterschiedliche Informationen anzeigt, dh 3 Controller binden an eine einzige Route .

Was ist der beste Weg, damit umzugehen?

Ich habe über einige Lösungen nachgedacht, aber keine scheint mir gut zu sein:

  1. Ein Controller, und in jeder Aktion test ich nur die Benutzerrolle:

    %Vor%

    Selbst wenn das den Job macht, IMO ist das offensichtlich kein gutes Design.

  2. Ein BackendController, der an 3 verschiedene Controller versendet:

    %Vor%

    Wie Nummer eins.

  3. Ich habe versucht, Controller dazu zu bringen, sich gegenseitig zu erweitern:

    %Vor%

    IMO, es ist ein besseres Design, aber ich kann es nicht schaffen. Das Routing-System stoppt auf dem ersten Controller, mit dem es übereinstimmt. Ich würde es gerne König der Cascading-Stil automatisch handeln (d. H. Wenn Benutzer Mitarbeiter ist dann gehen Sie zu PostStaffController, andernfalls, wenn Benutzer Moderator ist, gehen Sie zu PostModeratorController, sonst gehen Sie zu PostAdminController).

  4. Fügen Sie in meinem BlogBundle einen Listener zu kernel.controller hinzu, der den gleichen Job wie Nummer 2 macht?

Ich suche nach der am besten entwickelten und flexibleren Lösung. Es besteht die Möglichkeit, dass wir in Zukunft weitere Rollen hinzufügen.

    
iamdto 17.04.2012, 11:25
quelle

4 Antworten

1

IMHO, Sie sollten nicht verschiedene Controller für dieselbe Route basierend auf Rollen abfeuern. Es sind nur unterschiedliche Verantwortlichkeiten. Routen sind für ausgewählte Controller, Rollen sind für Privilegien. Nach einem Jahr wirst du dich nicht mehr an den Trick erinnern, dh. Wenn Sie versuchen, fügen Sie eine neue Rolle hinzu.

Natürlich ist das Problem der verschiedenen Inhalte für verschiedene Rollen ziemlich oft, so dass meine Lieblingslösungen in diesem Fall sind:

  1. Wenn der Controller für verschiedene Rollen sehr unterschiedlich ist, verwende ich bei Bedarf verschiedene Routen mit Umleitung.
  2. Wenn der Controller ähnlich ist, aber Inhalt ist anders, dh. verschiedenen Datenbankabfragebedingungen, benutze ich eine ähnliche Lösung wie Ihre 2., aber statt forwading, verwenden Sie private / geschützte Methoden vom selben Controller, um den Job zu erstellen. Es gibt einen Hack - Sie müssen die Rolle von oben nach unten überprüfen, dh. Überprüfen Sie zuerst ROLE_ADMIN, den nächsten ROLE_OPERATOR und den letzten ROLE_STAFF, denn wenn ROLE_ADMIN von ROLE_STAFF erbt, dann blockieren Sie den Block für den Benutzer.
  3. Wenn der Unterschied nur in einigen Informationsblöcken liegt, die für verschiedene Rollen ein- / ausgeblendet werden sollen, bleibe ich bei einem Controller und überprüfe die Rolle in der Vorlage, um zu bestimmen, welcher Block rendern soll oder nicht.
Łukasz Jakubek 09.08.2017 08:12
quelle
0

Wie wäre es mit einer automatisierten Version Ihrer zweiten Lösung? Wie:

%Vor%

Da ich dein Setup nicht habe, habe ich den obigen Code nicht getestet. Übrigens: Was ist der Unterschied zwischen den verschiedenen Methoden, etwas zu posten?

    
prehfeldt 17.04.2012 16:19
quelle
0

siehe Ссылка

sollte den Trick machen und sicherstellen, dass der security.context-Dienst injiziert wird

    
ken 18.04.2012 03:04
quelle
0

in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php

Es gibt eine Option zum Ersetzen der matcher_class , die in config.yml möglich sein sollte.

Wenn Sie die Unterklassen UrlMatcher und overRide matchRequest erstellen, die Vorrang vor der Pfadübereinstimmung haben (nur URL).

matchRequest nimmt eine Parameter $ Anfrage (Request Objekt)

Das Request-Objekt sollte die Benutzerinformationen enthalten, vorausgesetzt, der Security-Provider-Listener wird vor dem Router-Listener ausgeführt, und Sie können die Route auswählen, indem Sie die URL und die Benutzerrolle kombinieren. Die Routen werden in einem Array gespeichert, das mit dem Namen indiziert wird, sodass die Namen unterschiedlich sein müssen.

Sie könnten möglicherweise Namen wie post_index[USER] post_index[STAFF] post_index[MODERATOR]

verwenden

Um die URLs mit {{ path('post_index', {...}) }} zu generieren, müssen Sie auch die Unterklasse URLGenerator ersetzen und diese mit der Option generator_class in den Router injizieren.

    
Jason Hendry 02.09.2015 12:10
quelle

Tags und Links