web-dev-qa-db-fra.com

Laravel Stratégies - Comment passer plusieurs arguments pour fonctionner

J'essaie d'autoriser un personnage utilisateur à supprimer/mettre à jour le message. J'utilisais des stratégies pour ce faire, mais je ne pouvais transmettre qu'un paramètre à la fonction de stratégie. Si je passe plus que l'utilisateur et une autre variable, la variable n'est pas passée dans la fonction.

Modèles: l'utilisateur a de nombreux caractères, un personnage peut publier plusieurs messages. Donc, à des fins d'autorisation, je devrais comparer le caractère_id du message avec l'identifiant du personnage actuel ...-

Par docs , vous pouvez passer plus de multiples à la façade de la porte:

Gate::define('delete-comment', function ($user, $post, $comment) {
    //
});

Mais je n'ai pas réussi à le faire avec les politiques. Ce que je devais faire était d'injecter l'objet Request pour obtenir l'objet nécessaire à l'autorisation. Fondamentalement, je n'aurais même pas besoin de l'objet utilisateur.

public function update(User $user, Post $post)
{
    return $user->id === $post->user_id;
}

L'utilisation de l'objet Request fonctionne, mais cela semble très hacky. Existe-t-il un meilleur moyen d'y parvenir?

éditer:

Dans le CharacterLocationController j'ai une méthode show et je veux autoriser l'action avant d'afficher la ressource.

public function show(Request $request, Character $character, Location $location)
{
    $this->authorize([$location, $character]);
    ...
}

La politique est enregistrée comme ceci: 'App\Location' => 'App\Policies\LocationPolicy' dans le AuthServiceProvider

J'ai vidé le tableau transmis à la fonction de stratégie et il ne produit que le $location.

public function show(User $user, $data) {
    dd($data); // expecting location and character
    return !$location->private || $location->authorized->contains($this->character);
}
18
Johannes

Je pense qu'il y a peut-être une certaine confusion ici sur les fonctions qui font quoi.

Lorsque vous utilisez

Gate::define('delete-comment', function ($user, $post, $comment) {
    //
});

Ou dans le CommentPolicy

public function delete(User $user, Post $post, Comment $comment)
{
    return $user->id === $post->user_id;
}

Tout ce que vous faites, c'est définir les règles. À ce stade, nous ne sommes pas inquiets de passer quoi que ce soit, seulement que les objets que nous avons reçus peuvent ou devraient pouvoir interagir les uns avec les autres. La seule différence entre ces deux est lors de l'utilisation de politiques, c'est juste un moyen facile de résumer toutes vos règles dans une classe simple et facile à lire. Si vous avez une application avec potentiellement des centaines de tables et de modèles, cela deviendra rapidement déroutant si vous avez ces règles jonchées partout dans votre application afin que les politiques aident à les garder toutes organisées.

C'est lorsque vous vérifiez réellement si quelqu'un a la permission de faire quelque chose que vous devriez transmettre ces éléments. Par exemple, lorsque vous effectuez les opérations suivantes,

if (Gate::allows('delete-comment', [$post, $comment])) {
    // 
}

Ou si dans le CommentController

$this->authorize('delete', [$post, $comment]);

C'est ce qui contrôle les paramètres qui seront passés à la politique ou au Gate::define méthode. Selon les documents, le $user le paramètre est déjà ajouté pour vous, dans ce cas, vous n'avez qu'à vous soucier de passer le bon $post et $comment en cours de modification.

30
user1669496