Bonjour,

J'utilise Laravel-permission de Spatie pour gérer mes rôles et permissions. Mais j'ai un problème de conception pour le rôle du membre bannis (puis de l'implémentation de code). En ce qui me concerne, j'aimerai redirigé automatiquement le membre bannis vers une page spéciale bannis.

Est-ce la bonne façon de voir le rôle du banni ou vous feriez autrement ?

Je ne parle pas du fait que le membre n'aura qu'à recréer un compte pour tenter de passer outre, sauf avec diverses comparaisons (ip identiques, cookies .. ?).

Pour finir, si on part sur ma conception de rediriger systématiquement sur une page spécifique, par où l'implémenter ? Je n'arrive pas à trouver le point d'entré où faire cette vérification générale sans tomber dans une boucle (redirection impossible).

Sur le lien donné plus haut, il préconise de faire :

<?php
// Catching role and permission failures
// If you want to override the default 403 response, you can catch the UnauthorizedException using your app's exception handler:

public function render($request, Exception $exception)
{
    if ($exception instanceof \Spatie\Permission\Exceptions\UnauthorizedException) {
        // Code here ...
    }

    return parent::render($request, $exception);
}

J'ai tenté de mettre throw UnauthorizedException::forRoles('banished'); à la place de Code here ci-dessus.

Pour trouver le rôle du membre banni, je doit utiliser ceci : Auth::user()->hasRole('banished').

J'ai tenté un middleware dans le $middlewareGroups web.. Bref, je galère un peu à concevoir surtout, si c'est la bonne chose à faire.

4 réponses


Azorgh
Réponse acceptée

Forcément, puisque ton middleware est appliqué partout, même sur la page "vous êtes bannis !".
Tu peux donc rajouter une simple condition qui check la route actuelle dans le middleware par exemple, et de n'appliquer la redirection seulement si la route != "user.ban" par exemple. Ca reste une solution très simple, basique, mais efficace ^^

Tu peux aussi si tu le souhaite n'affecter le middleware que sur certaines routes, ou même certain groupes. A toi de voir, et à toi de jouer ;)

Hello,

Pour moi c'est clairement un middleware qu'il faut utiliser. Tu créé donc le middleware RedirectIfBanned que tu mets effectivement dans ton tableau "web" dans le Kernel.php. Et tout devrait rouler.

Dis toi qu'il s'agit du même principe que de regarder si l'utilisateur est connecté ou non pour accéder à cette page.
il s'agit de regarder si l'utilisateur est banni ou non pour accéder à cette page.

JeremyB
Auteur

Merci pour ta réponse et je suis bien d'accord pour une page spécifique.

Mais, si je veux gérer pour l'ensemble des pages qu'il clique (donc le bannir partout) pour le rediriger vers cette page spécifique, ça me fait une boucle et créé une erreur de redirection.. D'où peut-être mon erreur de conception sur cette façon de bannir, impossible de bannir sur toutes les pages (donc le supprimer dans ce cas, ou le bloquer sur toutes les actions spécifiques d'un membre lambda).

JeremyB
Auteur

J'avais complètement zappé cette idée.. checker l'URL en cours.. Super, je te remerci. ;)

EDIT : je mets le code pour ce a qui ça peut intéressé

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\URL;

class RedirectIfBanished
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $last_segment = substr(URL::current(), strrpos(URL::current(), '/') + 1);

        // Obligatoire si on veut pouvoir se décconecter
        if ($request->isMethod('post')) {
            return $next($request);
        }

        if (Auth::check() && Auth::user()->hasRole('banished')) {
            if ($last_segment === 'banished') {
                return $next($request);
            }

            return redirect('/banished');
        } else {
            if ($last_segment === 'banished') {
                return redirect()
                    ->back()
                    ->with('flash_message', [
                        'icon'    => 'ban',
                        'type'    => 'danger',
                        'title'   => 'Page inaccessible !',
                        'message' => 'Vous n\'êtes pas banni du site, inutile ainsi d\'accéder à cette page.
                            Continuez votre visite sur '. config('site.base.b-name')
                    ]);
            }

            return $next($request);
        }
    }
}

Ne pas oublier de mettre \App\Http\Middleware\RedirectIfBanished::class dans $middlewareGroups de \App\Http\Kernel.php.