2017-04-03 6 views
1

Ich möchte eine zeilenbasierte Zugriffskontrolle auf meiner Laravel-Anwendung einrichten (derzeit 5.2, warten auf 5.5 lts). Dies könnte im Controller geschehen, aber ich habe mich gefragt, ob es einen Weg gibt, es im Framework etwas tiefer zu gehen.Zeilenbasierte Zugriffssteuerung für Laravel Ergebnisse

Lassen Sie uns sagen, dass es diese Modelle:

P - project 
U - user (assigned to many projects) 
D - Device (assigned to one project) 
F - FAQ document (assigned to one project) 

Der aktuell angemeldete Benutzer nur die Geräte und FAQ-Dokumente sehen sollten, die ihre Projekte gehören.

Mein aktueller Versuch ist es, dies in der Steuerung zu tun. Rufen Sie den aktuellen Benutzer ab, suchen Sie nach einer generischen Berechtigung "auf alle Projekte zugreifen" und - falls nicht vorhanden - treten Sie dem Projekt für das angeforderte Modell bei, um das Ergebnis zu begrenzen. Dies muss für alle Abfragen repliziert werden, die für dieses Modell ausgeführt werden, und ich bin der Meinung, dass diese Art von Redundanz nicht perfekt ist.

Gibt es eine Möglichkeit, etwas wie ein Interface-Merkmal mit einer Methode withAccess() zu erstellen, die diese Modelle (Geräte- und FAQ-Dokument in meinem Beispiel) zwingt, diese Methode zu implementieren und die Abfrage einmal für die Modelldefinition auszuführen?

+0

Ich würde gerne Middleware (systemweite Middleware, die als Filter funktioniert) erstellen. Eigentlich habe ich nicht verstanden, was du mit zeilenbasierter Zugriffskontrolle meinst. – webDev

+0

Wie ich verstanden habe, funktioniert die Middleware gut für das Filtern einer Anfrage im Falle von keinem Zugriff, wie wenn Sie auf ein Gerät zugreifen möchten, das nicht zu einem Ihrer Projekte gehört. Aber was, wenn Sie auf eine Liste von Geräten zugreifen möchten? Wie könnte eine Middleware hier nützlich sein? (z.B.Filtern der Ergebnismenge) – McGo

+0

Nein, Sie können alles mit dieser Middleware machen, bei Erfolg können Sie Ihre Geräteliste an die nächste Anfrage weiterleiten und in Ihrem Controller abrufen oder auf der nächsten Seite anzeigen – webDev

Antwort

3

Eine Sache, die ich mir vorstellen kann, ist die Verwendung eines wiederverwendbaren Bereichs für jedes Modell.

z.B.

In Ihrem Controller:

$devices = Device::ViewableDevices()->get(); 

und in Ihrem Device Modell:

public function scopeViewableDevices($query) 
{ 

    return $query->whereHas('project', function($query) { 
     $query->whereHas('user', function($query) { 
      $query->where('user_id', Auth::user()->id); 
     } 
    }); 

} 

Die Abfrage könnte falsch sein im Vergleich zu, wie die Daten gespeichert werden und die Logik, die Sie versuchen zu erreichen, aber was Ich meine in dem Umfang ist, das Projekt für das Gerät zu finden, dann den Benutzer für das Projekt zu finden und zu sehen, ob es zu dem angemeldeten Benutzer gehört.

Damit dies funktionieren Sie das Einrichten eine project Beziehung im Device Modell und eine user Beziehung im Project Modell benötigen würden.

z.B.

// Device.php 
public function project() { 
    return $this->hasOne('App\Project', 'id', 'project_id'); 
} 

// Project.php 
public function user() { 
    return $this->belongsTo('App\User', 'id', 'user_id'); 
} 

Die Beziehungen könnten weg sein, habe ich immer die Reihenfolge gemischt, aber ich php artisan tinker im Allgemeinen sicher zu stellen, dass sie funktionieren.

Scopes Docs

Relationship Docs

Die einzige andere, was ich vorschlagen würde, ist, um sicherzustellen, haben Sie Indizes (Indizes?) Auf dem Fremdschlüsselspalten, z.B. project_id, user_id und anderen helfen sie, Ihre Anfragen zu beschleunigen, besonders wenn Ihre Tabellen ziemlich groß sind.

+1

Scope war das Schlüsselwort, das ich vermisste! Wunderbar, ich lese das durch, aber der erste Absatz beschreibt genau, wonach ich gesucht habe. – McGo

+0

kein Problem, manchmal ist das ein Wort alles, was Sie brauchen, um zu finden, was Sie suchen, froh, zu helfen. – martincarlin87

Verwandte Themen