J'utilise cette structure de niveaux d'utilisateurs:
class ClientController extends Controller { public function index() { return Client::all(); } // ... }
J'ai besoin de contrôler les utilisateurs pour accéder aux données de la base de données. L'employé ne peut accéder qu'à ces données qu'il a stockées. Le responsable d'unité peut également accéder à ses propres données et données de son employé. Le gestionnaire de groupe peut accéder aux données du groupe entier. Et le propriétaire de l'entreprise peut accéder à tout.
J'ai quelques contrôleurs comme celui-ci:
Company Owner - Group Manager -- Unit Manager ---Employee
Quelle est la meilleure pratique dans Laravel pour contrôler l'accès aux données (pas le contrôleur) dans certains contrôleurs, mais pas partout? Y a-t-il une bonne implémentation pour ce problème?
4 Réponses :
Vous pouvez créer un middleware pour chaque rôle, puis dans votre fichier web.php, utiliser des groupes de routes pour attribuer l'accès aux routes auxquelles les utilisateurs peuvent accéder. Donc, pour un itinéraire auquel l'employé et le responsable d'unité peuvent accéder, vous passez les deux middleware, pour ceux auxquels seul le responsable de groupe peut accéder, il vous suffit de passer le gestionnaire de groupe.
Chaque utilisateur peut accéder au contrôleur client. Le différent est ce qu'ils peuvent y voir. Comment puis-je dire que «l'employé» ne peut voir que les données qu'il a stockées?
Dans ce cas, il s’agit simplement d’un problème de requête. Si vous stockez des données, vous devez stocker une référence à l'utilisateur qui les a insérées. L'ID de l'utilisateur. Lorsque vous appelez les données, vous interrogez la base de données pour les fichiers où l'ID de la personne qui les a placés est le même que l'ID des utilisateurs connectés. Donc, pour chaque stockage de fichier, vous avez une entrée dans votre dB qui aurait une référence au fichier. Ou vous utilisez une structure de fichiers unique par utilisateur.
il n'y a pas de fichiers, juste des données dans la base de données. L'ID_utilisateur est stocké dans les enregistrements. Oui, c'est un problème de requête :) Le problème est: si je connais le user_id, je peux trouver ses subordonnés, mais je veux trouver un moyen de savoir ce que peut voir l'utilisateur. S'il est vendeur, il ne peut voir que ses enregistrements. S'il est responsable d'unité, il peut voir ses propres données, et toutes les données de ses employés. Mais j'ai de nombreux contrôleurs et je ne veux pas dupliquer ce code de filtre. Existe-t-il un moyen de le définir en un seul endroit et de l'utiliser là où j'en ai besoin?
définissez-le dans le modèle. laravel.com/docs/5.7/eloquent-mutators#defining-a- mutateur y aller comme référence.
En route. Un bon emplacement pour tous les middlewares.
Route::get('/', function () { ... })->middleware('web');
Le middleware est le bon endroit pour le contrôle d'accès. Pour le middleware de groupe, vous pouvez utiliser ce format
Route::put('post/{id}', function ($id) { // })->middleware('role:Employee');
Pour une seule route
Route::group(['middleware' => ['role:Company Owner']], function() { Route::get('/', 'AdminController@welcome'); Route::get('/manage', ['middleware' => ['permission:manage-admins'], 'uses' => 'AdminController@manageAdmins']); }); Route::group(['middleware' => ['role:Employee']], function() { Route::get('/', 'AdminController@welcome'); Route::get('/manage', ['middleware' => ['permission:manage-admins'], 'uses' => 'AdminController@manageAdmins']); });
Vous pouvez utiliser un package pour le contrôle d'accès de base de rôle utilisateur
Peut-être que la question n'est pas assez claire, mais j'ai trouvé une solution:
public function allEmployeeFlatten() { $employees = new Collection(); foreach ( $this->employee()->get() as $employee ) { $employees->push( $employee ); // run only if the user is on a leader level if ( $employee->user_role_id != 5 ) { $employees = $employees->merge( $employee->allEmployeeFlatten() ); } } return $employees; }
Voici le code allEmployeeFaletten () code du modèle
User
> fonction:
<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; use Auth; use App\User; class DataAccessScope implements Scope { /** * Apply the scope to a given Eloquent query builder. * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function apply(Builder $builder, Model $model) { // find the actual user $user_id = Auth::user()->id; $user = User::find( $user_id ); // get all employees $employees = $user->allEmployeeFlatten(); // get only the employee's ids $user_ids = $employees->pluck('id'); // add current user's id too $user_ids->push( $user_id ); // add the condition to every sql query $builder->whereIn('user_id', $user_ids); } }
Cette portée ajoute une condition à toutes les requêtes SQL chaque fois que j'utilise la portée.
utilisez les rôles et le concept de permission .. si vous voulez vous simplifier la vie, voici quelques bons paquets pour vous. github.com/spatie/laravel-permission et github.com/Zizaco/entrust
Bons conseils, mais comment puis-je dire que l'utilisateur ne peut voir que les données qu'il a stockées?
Vous pouvez faire
créé_by code> ou
mise à jour_by code> Colonne dans les tables pour indiquer qui est créé les données .. Puis récupéré les données basées sur cette colonne.