symfony2在请求头中设置_target_path会重复app_dev.php
我正在使用以下代码在成功登录后生成重定向:symfony2在请求头中设置_target_path会重复app_dev.php,php,symfony,login,Php,Symfony,Login,我正在使用以下代码在成功登录后生成重定向: $request->request->set('_target_path', $this->router->generate('renew_subscription')); 输出url为: 如何确保app_dev.php不会重复两次?我觉得Stru_不够干净 编辑: 我正在登录侦听器中设置此选项。我发现登录处理程序无法工作,因为securitymanager服务尚未正确启动: portfolio_change_and_log
$request->request->set('_target_path', $this->router->generate('renew_subscription'));
输出url为:
如何确保app_dev.php不会重复两次?我觉得Stru_不够干净
编辑:
我正在登录侦听器中设置此选项。我发现登录处理程序无法工作,因为securitymanager服务尚未正确启动:
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 }
谢谢 您可以在窗体视图中设置它,而不是在控制器或服务中设置\u target\u paath: 将此字段添加到登录表单:
<input type="hidden" name="_target_path" value="YourRouteName" />
“YourRouteName”是路线的名称您应该设置控制器并使用重定向响应 这是一个监听器,我用它来确保下一条路线是表单中计划好的下一步,这样用户就不会到处乱跳。我查查看是否
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 }
希望这有帮助。如果你有任何问题,请告诉我
编辑1 如果您试图在登录后运行重定向,那么您应该使用这样的处理程序
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' }
我不记得我在哪里找到了如何做到这一点,但这是在到处寻找例子之后。我也有一个注销处理程序,我从同一个地方得到。我相信如果你搜索类名,你会在某处找到这个例子 因此,有一种很好的方法可以使用登录处理程序进行重定向。 见B.Rad的答案 我一直在寻找一种在登录侦听器中实现它的方法,因为当您实例化登录处理程序时,令牌还没有被用户填充。只有在您调用AuthenticationSuccess后,才会填充它。 我对用户有依赖性,我首先用构造函数加载它,但它不起作用。使用setter并从
内部调用对AuthenticationSuccess
的依赖性是解决方案
无论如何,我们也可以从登录侦听器执行重定向,使用:
$request = $event->getRequest();
$route = strreplace('app_dev.php', '', $this->router->generate('your_route'))
$request->request->set('_target_path', $route );
尝试使用绝对URL而不是相对URL
$request = $event->getRequest();
$route = $this->router->generate('your_url', [], UrlGeneratorInterface::ABSOLUTE_URL)
$request->request->set('_target_path', $route);
文档您在哪里设置此设置?我在登录侦听器中设置此设置。不适用于我的情况,我在登录侦听器中设置此设置。好的,我希望在登录检查和成功身份验证后重定向此设置。如果symfony正在处理检查部分,我如何使用控制器?您是使用fos用户包还是仅使用symfony?我使用fosub,yes@S我在下半场更新了我的答案。我想这应该可以解决你的问题。嗯,不幸的是,在我的情况下,我需要一个登录列表。我已经尝试过登录处理程序,除了我依赖于某个没有及时更新的东西(我有另一个服务将tokenstorage作为参数,并且这个token还没有填充用户信息)之外,其他都可以正常工作