【发布时间】:2014-12-26 16:09:33
【问题描述】:
我正在尝试在侦听器中进行重定向,但它不起作用。
我的听众:
<?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'));
}
}
}
我需要这个,因为我有 2 个登录表单:一个用于 PC,一个用于移动设备。因此,如果用户在登录/密码时出错,我需要显示正确的页面 /login 或 /m/login。
我的脚本有效。如果我取消注释 var_dump('Hello'); 我会看到“你好”。除了我的重定向之外,一切都很好。我不知道为什么。我没有错误,symfony 只是不关心并将我重定向到 /login。显然这是“正常的”,我并不孤单,但我找不到解决方案。我刚刚在某个需要 Dispacher 的地方读到,但我不知道它是如何工作的。
如果你有一个很棒的解决方案。
编辑
我的 UserBundle/[...]/service.yml
# authentication failure event listener
acme_user.security.authentication_failure_event_listener:
class: Acme\UserBundle\Listener\AuthenticationListener
arguments: [@router]
tags:
- { name: kernel.event_listener, event: security.authentication.failure, method: onAuthenticationFailure }
# authentication success event listener
acme_user.security.interactive_login_listener:
class: Acme\UserBundle\Listener\AuthenticationListener
arguments: [@router]
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onAuthenticationSuccess }
我的 UserBundle/[...]/routing.yml
mobile_login:
pattern: /m/login
defaults: { _controller: AcmeUserBundle:Mobile:login }
编辑阿卜杜拉·阿尔法克
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,
));
}
【问题讨论】:
-
显示您如何为侦听器和您的 mobile_login 路由定义服务。
-
@jakon 我编辑了。如果您需要更多信息,请告诉我。
标签: symfony