我使用以下代码在成功登录后生成重定向:
$request->request->set('_target_path', $this->router->generate('renew_subscription'));
输出网址为:
http://mysite.dev/app_dev.php/app_dev.php/renew_subscription
如何确保app_dev.php不会重复两次?我觉得str_replace不够干净。
编辑:
我在登录监听器中设置它。我发现登录处理程序无法正常工作,因为安全管理器服务尚未正确启动:
portfolio_change_and_login_listener:
class: %portfolio_change_and_login_listener.class%
arguments: [@security.authorization_checker, @doctrine.orm.entity_manager, @session, @security_manager, @router]
tags:
- { name: kernel.event_listener, event: portfolio_change, method: onPortfolioUserChange }
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin, priority: 255 }
谢谢!
答案 0 :(得分:2)
而不是在控制器或服务中设置_target_paath,您可以在表单视图中设置它:
将此字段添加到您的登录表单中:
<input type="hidden" name="_target_path" value="YourRouteName" />
&#34; YourRouteName&#34;是您的路线名称
答案 1 :(得分:0)
您应该设置控制器并使用RedirectResponse
这是一个监听器,我用它来确保下一个路由是表单中计划的下一步,这样用户就无法跳转。我查看是否
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class SampleListener
{
protected $em;
protected $token_storage;
private $router;
function __construct(TokenStorageInterface $token_storage, EntityManager $em, $router)
{
$this->token_storage = $token_storage;
$this->em = $em;
$this->router = $router;
}
public function onKernelController(FilterControllerEvent $event)
{
//some other checks go here
$route = $event->getRequest()->attributes->get("_route");
$appStep = $app->getAppStep();
if ($route != $appStep) {
//Check to see if the route is going to the planned next stp
$stepsVisited = explode(",", $app->getVisited());
if (in_array($route, $stepsVisited)) {
//if its not going to the next planned step then make sure its a path we visited before.
return;
} else {
$url = $this->router->generate($appStep, array("appId" => $appId));
$event->setController(function () use ($url) {
return new RedirectResponse($url);
});
}
}
}
}
变量appstep只是对路径名称的引用,如下所示。
/**
* @Route("/place/{appId}", name="Place")
*/
这就是我的服务。这是在yml
中完成的sample.action_listener:
class: Bundle\Name\EventListener\AppSecurityListener
arguments:
- @security.token_storage
- @doctrine.orm.entity_manager
- @router
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
希望这会有所帮助。如果您有任何疑问,请告诉我。
如果您尝试在登录后运行重定向,那么您应该使用这样的处理程序。
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
{
protected $router;
protected $security;
public function __construct(Router $router, SecurityContext $security)
{
$this->router = $router;
$this->security = $security;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
if ($this->security->isGranted('ROLE_ADMIN')) {
$response = new RedirectResponse($this->router->generate('AnnotationName 4'));
} elseif ($this->security->isGranted('ROLE_B')) {
$response = new RedirectResponse($this->router->generate('AnnotationName1'));
}
// elseif ($this->security->isGranted('ROLE_ADMIN'))
// {
// // redirect the user to where they were before the login process begun.
// $referer_url = $request->headers->get('referer');
//
// $response = new RedirectResponse($referer_url);
// }
else {
$response = new RedirectResponse($this->router->generate('Home'));
}
return $response;
}
}
然后,您需要在服务文件中设置参数和服务
parameters:
bundle_name.service.login_success_handler.class: Bundle\Name\Service\LoginSuccessHandler
services:
bundle_name.service.login_success_handler:
class: %bundle_name.service.login_success_handler.class%
arguments: [@router, @security.context]
tags:
- { name: 'monolog.logger', channel: 'security' }
我无法记住我在哪里弄清楚如何做到这一点,但经过大量的环顾四周寻找例子。我也有一个登出处理程序,我从同一个地方。我相信如果你搜索类名,你会在某个地方找到这个例子。
答案 2 :(得分:0)
因此,有一种使用登录处理程序进行重定向的好方法。 见B. Rad答案。
我一直在寻找一种从登录侦听器中创建它的方法,因为当您实例化登录处理程序时,该令牌尚未填充该用户。仅在您致电onAuthenticationSuccess
后填充。
我有一个依赖用户,我首先用构造函数加载它,它不起作用。使用setter并从onAuthenticationSuccess
内调用依赖是解决方案
无论如何,我们也可以使用以下命令从登录监听器进行重定向:
$request = $event->getRequest();
$route = strreplace('app_dev.php', '', $this->router->generate('your_route'))
$request->request->set('_target_path', $route );
答案 3 :(得分:0)
尝试使用绝对URL代替相对URL。
$request = $event->getRequest();
$route = $this->router->generate('your_url', [], UrlGeneratorInterface::ABSOLUTE_URL)
$request->request->set('_target_path', $route);
文档https://symfony.com/doc/current/routing.html#generating-absolute-urls