0
votes

Middleware Laravel pour contrôler l'accès des utilisateurs aux données

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?


3 commentaires

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 ou mise à jour_by Colonne dans les tables pour indiquer qui est créé les données .. Puis récupéré les données basées sur cette colonne.


4 Réponses :


1
votes

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.


4 commentaires

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.



0
votes

En route. Un bon emplacement pour tous les middlewares.

Route::get('/', function () {  ...  })->middleware('web');


0 commentaires

2
votes

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

https://github.com/Zizaco/entrust


0 commentaires

0
votes

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.


0 commentaires