我正在使用Symfony和FOS UserBundle,我想阻止经过身份验证的用户访问登录,注册或密码重置页面。任何访问这些页面的尝试都应该导致重定向到主页。
我已经读过你可以复制控制器来进行这些更改,但这意味着当有更新并再次应用这些更改时手动更新复制的代码,这并不理想。
还有可能使用事件订阅者。这是我的实现,它可用于阻止注册表单,但我仍然可以访问重置页面和登录页面。
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\FOSUserEvents;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
class FOSUserSubscriber implements EventSubscriberInterface
{
/**
* @var Router
*/
protected $router;
/**
* @var TokenStorage
*/
private $tokenStorage;
public function __construct(Router $router, TokenStorage $tokenStorage)
{
$this->router = $router;
$this->tokenStorage = $tokenStorage;
}
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_INITIALIZE => 'forwardToRouteIfUser',
FOSUserEvents::RESETTING_RESET_REQUEST => 'forwardToRouteIfUser',
FOSUserEvents::RESETTING_RESET_INITIALIZE => 'forwardToRouteIfUser', //['forwardToRouteIfUser',-100]
FOSUserEvents::RESETTING_RESET_SUCCESS => 'forwardToRouteIfUser',
FOSUserEvents::RESETTING_RESET_COMPLETED => 'forwardToRouteIfUser',
);
}
public function forwardToRouteIfUser(GetResponseUserEvent $event)
{
if (!$this->tokenStorage->getToken()->isAuthenticated()) {
return;
}
$url = $this->router->generate('home');
$response = new RedirectResponse($url);
$event->setResponse($response);
}
}
Service.yml
Foo\BarBundle\EventListeners\FOSUserSubscriber:
arguments: ['@router','@security.token_storage']
tags:
- { name: kernel.event_subscriber }
如果使用Controller确实是唯一的方法,请提供一个不涉及复制大块代码的示例。
版本:
"friendsofsymfony/user-bundle": "^2.0",
"symfony/symfony": "3.4.*",
答案 0 :(得分:0)
您可以实际覆盖FOSUserBundle控制器,而无需在有新版本的FOSUserBundle时手动更新它们,方法是使用return parent::loginAction($request);
以下是SecurityController
的示例,以防止已登录的用户访问登录页面:
// src/UserBundle/Controller/SecurityController.php
namespace UserBundle\Controller;
use FOS\UserBundle\Controller\SecurityController as BaseController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Controller managing the login (extends FOSUserBundle SecurityController)
*/
class SecurityController extends BaseController
{
/**
* Customize the login action, to redirect already logged in users
* to the homepage
*
* @param Request $request
* @return Response
*/
public function loginAction(Request $request)
{
/* If the user is already logged in, redirect him to the homepage */
if ($this->get(Services::SECURITY_AUTHORIZATION_CHECKER)->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
/* Redirect the user to the homepage */
return new RedirectResponse($this->generateUrl('homepage'));
}
/* Call the parent method */
return parent::loginAction($request);
}
}
您可以将其应用于RegistrationController
和ResettingController
。