首页 > 解决方案 > 根据属性重定向用户

问题描述

好吧,我想做的是检查用户状态是否为“待处理”,如果是,我会将他重定向到“/待处理”页面。

现在我需要对几乎整个网站进行此项检查。

我尝试了决策经理,但无法重定向,还有其他方法吗?

这应该只为登录的用户调用

安全.yaml

access_decision_manager:
        service: App\Security\StatusAuthenticator

和 StatusAuthenticator

<?php

namespace App\Security;


use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;

class StatusAuthenticator implements AccessDecisionManagerInterface
{
    /**
     * @param TokenInterface $token
     * @param array $attributes
     * @param null $object
     * @return bool|void
     */
    public function decide(TokenInterface $token, array $attributes, $object = null)
    {
        if($token->getUser()->getStatus() == User::USER_STATUS_PENDING) {
            // Needs to be redirected to /pending
            return false;
        }

        return true;
    }
}

标签: phpsymfonysymfony5

解决方案


由于您需要“在几乎整个网站上进行检查”,因此您可以使用一个EventListener会在每个请求上触发的功能,您可以在那里检查您是否有经过身份验证的用户及其状态。

// src/EventListener/PendingUserListener.php
namespace App\EventListener;

use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;

class PendingUserListener implements EventSubscriberInterface
{
    /**
     * @var Security
     */
    private $security;

    /**
     * @var UrlGeneratorInterface
     */
    private $urlGenerator;    

    public function __construct(Security $security, UrlGeneratorInterface $urlGenerator)
    {
        $this->security = $security;
        $this->urlGenerator = $urlGenerator;
    }

    public static function getSubscribedEvents()
    {
        return [ KernelEvents::REQUEST => 'onKernelRequest' ];
    }

    public function onKernelRequest(RequestEvent $event)
    {
        $pending_route = 'pending';
        $user = $this->security->getUser();

        if (!$event->isMasterRequest()) {
            return;
        }

        if (!$user instanceof UserInterface) {
            return;
        }

        // Check if the requested page is 'pending', prevent redirect loops
        if ($pending_route === $event->getRequest()->get('_route')) {
            return;
        }

        // RedirectResponse expects a full url, generate from route name
        if (User::USER_STATUS_PENDING == $user->getStatus()) {
            $event->setResponse(
                new RedirectResponse($this->urlGenerator->generate($pending_route))
            );
        }
    }
}

推荐阅读