Symfony 如何在侦听器中进行重定向
我试图在侦听器中进行重定向,但它不起作用 我的听众:Symfony 如何在侦听器中进行重定向,symfony,Symfony,我试图在侦听器中进行重定向,但它不起作用 我的听众: <?php // AuthenticationListener.php namespace Acme\UserBundle\Listener; use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony
<?php
// AuthenticationListener.php
namespace Acme\UserBundle\Listener;
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Routing\Router;
use Symfony\Component\HttpFoundation\RedirectResponse;
class AuthenticationListener
{
protected $router;
public function __construct(Router $router)
{
$this->router = $router;
}
public function onAuthenticationFailure(AuthenticationFailureEvent $event)
{
if(preg_match("/m\/login/", $_SERVER['HTTP_REFERER'])){
// var_dump('Hello'); die();
return new RedirectResponse($this->router->generate('mobile_login'));
}
}
public function onAuthenticationSuccess(InteractiveLoginEvent $event)
{
if(preg_match("/m\/login/", $_SERVER['HTTP_REFERER'])){
return new RedirectResponse($this->router->generate('mobile_home'));
}
}
}
My UserBundle/[…]/routing.yml
mobile_login:
pattern: /m/login
defaults: { _controller: AcmeUserBundle:Mobile:login }
编辑Abdallah Arffak
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_MODO: ROLE_USER
ROLE_ADMIN: ROLE_MODO
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_MODO, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
mobile:
pattern: ^/m
anonymous: ~
form_login:
check_path: /m/login_check
login_path: /m/login
default_target_path: /m/admin
logout:
path: /m/logout
target: /
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout: true
anonymous: true
switch_user: true
remember_me:
key: "%secret%"
lifetime: 31536000
path: /
domain: ~
always_authenticate_before_granting: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/m/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
MobileController.php
<?php
namespace Acme\UserBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\SecurityContext;
class MobileController extends Controller
{
public function loginAction(Request $request)
{
/** @var $session \Symfony\Component\HttpFoundation\Session\Session */
$session = $request->getSession();
// get the error if any (works with forward and redirect -- see below)
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} elseif (null !== $session && $session->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = '';
}
if ($error) {
// TODO: this is a potential security risk (see http://trac.symfony-project.org/ticket/9523)
$error = $error->getMessage();
}
// last username entered by the user
$lastUsername = (null === $session) ? '' : $session->get(SecurityContext::LAST_USERNAME);
$csrfToken = $this->container->has('form.csrf_provider')
? $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate')
: null;
return $this->render('AcmeUserBundle:Mobile:login.html.twig', array(
'last_username' => $lastUsername,
'error' => $error,
'csrf_token' => $csrfToken,
));
}
尝试这样编写服务声明:
services:
myservice:
class: My\MyBundle\MyService
arguments: [ @router ]
scope: request
我认为您错过了scope属性。您不必通过“侦听器”
最好的方法是通过安全检查
security.yml:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
mobile:
pattern: ^/m
anonymous: ~
form_login:
check_path: /m/login_check
login_path: /m/login
default_target_path: /m/admin
logout:
path: /m/logout
target: /
main:
pattern: ^
anonymous: ~
form_login:
check_path: /login_check
login_path: /login
default_target_path: /admin
logout:
path: /logout
target: /
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/m/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
routing.yml:
mobile_login:
pattern: /m/login
defaults: { _controller: AcmeUserBundle:Mobile:login }
mobile_check_special:
pattern: /m/login_check
mobile_logout_special:
pattern: /m/logout
尝试以下未经测试的方法:
security.yml:
...
firewalls:
some_area:
...
form_login:
failure_handler: custom.security.authentication_failure_handler
login_path: /login
check_path: /login_check
logout:
path: /logout
target: /
...
AuthenticationFailureHandler.php
class AuthenticationFailureHandler extends DefaultAuthenticationFailureHandler
{
private $router;
public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options, LoggerInterface $logger = null, RouterInterface $router)
{
parent::__construct($httpKernel, $httpUtils, $options, $logger);
$this->router = $router;
}
....
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
if(preg_match("/m\/login/", $_SERVER['HTTP_REFERER'])){
return $this->httpUtils->createRedirectResponse($request, $this->router->generate('mobile_login'));
}
return parent::onAuthenticationFailure($request, $exception);
}
}
服务配置:
....
<service id="custom.security.authentication_failure_handler" class="%custom.security.authentication_failure_handler.class%" public="false">
<argument type="service" id="kernel" />
<argument type="service" id="security.http_utils" />
<argument type="collection" />
<argument type="service" id="logger" on-invalid="ignore" />
<argument type="service" id="router" />
</service>
....
。。。。
....
显示您如何为侦听器定义服务以及您的手机登录路径。@jakon我编辑过。如果您需要更多信息,请告诉我。获取错误:InactiveScopeException:您无法创建非活动范围(“请求”)的服务(“acme.security.authentication\u failure\u event\u listener”)。您是否可以在服务声明末尾添加lazy:true,然后重试!删除作用域和惰性选项并更改您的响应,如下所示:AuthenticationFailureEvent(AuthenticationFailureEvent$event){if(preg_match(“/m\/login/”,$\u SERVER['HTTP\u REFERER']){$url=$this->router->generate('mobile\u login');$response=new RedirectResponse($url);$event->setResponse($response);}看看这篇文章,我想你也必须添加内核控制器功能:同样,我进入m/login,输入错误登录,然后被重定向到/login,并显示错误消息。我完全安全地编辑了我的第一篇文章。ymlCan你能给我看操作代码=>AcmeUserBundle:Mobile:login不好,我是个白痴,忘了更改
到
....
<service id="custom.security.authentication_failure_handler" class="%custom.security.authentication_failure_handler.class%" public="false">
<argument type="service" id="kernel" />
<argument type="service" id="security.http_utils" />
<argument type="collection" />
<argument type="service" id="logger" on-invalid="ignore" />
<argument type="service" id="router" />
</service>
....