根据属性重定向用户
Redirect users based on attribute
好吧,我想做的是检查用户状态是否为“待处理”,如果是,我会将他重定向到“/待处理”页面。
现在我需要对几乎整个网站进行检查。
我尝试使用决策管理器但无法重定向,还有其他方法吗?
这应该只为登录用户调用
security.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;
}
}
因为你需要“在几乎整个网站上检查这个”,你可以使用一个 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))
);
}
}
}
好吧,我想做的是检查用户状态是否为“待处理”,如果是,我会将他重定向到“/待处理”页面。
现在我需要对几乎整个网站进行检查。
我尝试使用决策管理器但无法重定向,还有其他方法吗?
这应该只为登录用户调用
security.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;
}
}
因为你需要“在几乎整个网站上检查这个”,你可以使用一个 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))
);
}
}
}