Besoin d'aide ?

Meilleurs moyen utilisateur ne peuvent gérer que leurs posts

  • Avatar de christophecontard
    Membre depuis :
    26/01/2019
    Messages :
    6

    Bonjour,
    Je débute sur laravel et je suis plutot developpeur du dimanche.
    Je suis depuis quelques temps plusieurs tutos et j'arrive maintenant à gerer des modeles et à créer des petites plateformes de type blogs.
    Jusqu'à present je gerais des plateforme mono-utilisateur ou j'étais le seul admin ce qui facilite plutot les choses.

    Je suis à present sur une plateforme de type blog avec plusieurs utilisateurs qui peuvent poster des articles et qui bien entendu devront pouvoir editer, supprimer, ajouter leurs articles. La les tutos se font plus rares.

    J'arrive bien à gerer l'ensemble et un utilisateur ne voit sur son backoffice que ses propres posts. Par contre si il change les ID des posts dans les urls il a bien accés à tous les posts de l'aaplication. Il peut ainsi les supprimer et editer.

    Donc je cherche la meilleur méthode pour empecher cela.

    Je peux ajouter une condition directement dans le Controller mais je ne trouve pas la solution terrible. Peut-être est-ce la bonne ?
    Je m'oriente plutot vers un middleware que j'appliquerais sur le groupe de routes edit/update/delete et j'appliquerais une fonction permettant de verifier que l'ID tranbmis est bien égal à l'user_id de la table post.
    Cette fonction pourrait être facilement dupliquée sur tout autre modele à venir.

    Donc je me demande si cette solution est la bonne. J'ai essyé quelques métodes mais je n'arrive pas à faire remonter l'id tranmise dans l'url à mon middleware. Ne voyant que peut d'infos sur cette métode sur le net je me demande donc si je pars dans une mauvaise direction.

    Si quelqu'un pouvait m'orienter ce serait super.

    Je précise, je suis sous laravel 5.7 avec la version Boilerplate bootstrap.

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2397

    Bonsoir,

    En général on passe pas les policies. C'est l'approche qui me paraît simple et claire.

    J'ai publié un exemple de blog avec ce système appliqué.

  • Avatar de christophecontard
    Membre depuis :
    26/01/2019
    Messages :
    6

    Super ça me parait mieux comme solution que d'encombrer les controlleurs avec tout un tas de condition.
    J'ai repris des bouts de code par ci par là sur ton blog mais j'ai bien l'impression qu'encore une fois l'id qui est dans l'url ne passe pas au controlleur. Du coup personne ne peut acceder à la route quand j'active le controlleur.

    J'avais cru comprendre en lisant un article quelque part que l'id de l'url ne devait pas être suivi d'autre chose pour qu'il puisse être pris en compte. Est-ce bien le cas ? Car j'ai des url pour modifier qui sont de type /Post/{id}/edit

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2397

    C'est juste les paramètres optionnels qui ne doivent pas être suivis par autre chose, ce qui est logique ;)

    Dans ton cas ça doit fonctionner...

  • Avatar de christophecontard
    Membre depuis :
    26/01/2019
    Messages :
    6

    Aprés plusieurs heures, quelques litre de café et je ne sais combien de ligne de code observé par ci par là je retombe toujours sur la même erreur. Bref je n'arrive pas à faire fonctionner ce satané middleware.
    J'ai donc repris point pour point le middleware sur le blog que tu m'as montré mais même là ça bloque.

    ce que j'ai fais :

    • creer une policy via php artisan
      Dedans j'ai mis ma function pour gerer mes posts (qui s'appelle centre mais bon)

      public function manage(User $user, Centre $centre)
      {

      return $user->id === $centre->user_id;
      }

      J'ai ensuite ajouté cette policy dans AuthServiceProvider comme ceci

      protected $policies = [
      //'App\Model' => 'App\Policies\ModelPolicy',
      Centre::class => Centrepolicy::class,
      ///'App\Model\Centre' => 'App\Policies\CentrePolicy',
      ];

      Puis au final j'appelle le middleware sur la route d'edition d'un post comme ceci :

      Route::group(['namespace' => 'Centre'], function () {

      Route::get('centres/create', 'CentreController@create')->name('centre.create');
      Route::get('centres', 'CentreController@index')->name('centre.index');
      Route::post('centres/store', 'CentreController@store')->name('centre.store');
      });
      Route::group(['prefix' => 'centres/{centre}', 'namespace' => 'Centre'], function () {
      Route::get('/edit', 'CentreController@edit')->name('centre.edit')->middleware('can:manage,centre');
      Route::get('/show', 'CentreController@show')->name('centre.show');
      Route::put('/update', 'CentreController@update')->name('centre.update');
      Route::get('/delete', 'CentreController@destroy')->name('centre.destroy');

      });

    et la du coup plus personne ne peut acceder aux page d'edition (erreur 403).
    Quand je regarde la barre de debug j'ai bien ma gate mais qui retourne NULL avec ce type d'info

    error

    array:4 [▼
    "ability" => "manage"
    "result" => null
    "user" => 4
    "arguments" => "[0 => Object(App\models\Centre)]"
    ]

    Le middleware ressort bien l'id de l'utilisateur (ici 4) mais niveau argument il y a un probleme que je n'arrive pas à resoudre.

  • Avatar de christophecontard
    Membre depuis :
    26/01/2019
    Messages :
    6

    J'ai trouvé. J'avais oublié une majuscule sur le namespace dans mon model.
    Des heures pour une majuscule... C'est fou de ne pas avoir une erreur plus explicite à ce niveau.

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2397

    Encore ça aurait pu être une minuscule, encore plus frustrant :)

  • Avatar de christophecontard
    Membre depuis :
    26/01/2019
    Messages :
    6

    Du coup je croyais que ca marchait puisque ça filtrait bien les deletes, les edit et les show sur mon controller.
    Mais j'avais pas fait gaffe que le middleware maintenant me bloque tout le monde sur les update. Je peux bien afficher le formulaire pour editer mais quand ça part en update, pouf, bloqué.
    toute les routes sont pourtant dans un même groupe comme ceci :

    Route::group(['prefix' => 'centres/{centre}', 'namespace' => 'Centre', 'middleware' => ['can:manage,centre']], function () {
    Route::get('/edit', 'CentreController@edit')->name('centre.edit');
    Route::get('/show', 'CentreController@show')->name('centre.show');
    Route::put('/update', 'CentreController@update')->name('centre.update');
    Route::get('/delete', 'CentreController@destroy')->name('centre.destroy');

    La structure des url est la même avec evidement le même parametre. La seul chose que je vois en difference sur le blog envoyé c'est l'utilisation de '{status?}' dans la route. Il doit y avoir un truc sur les updates que je ne saisis pas.

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2397

    C'est curieux que ça passe pas parce que le code est identique...

    Par contre un verbe GET pour un delete c'est pas trop adapté.

Vous ne pouvez pas répondre à ce sujet.