Symfony2:登录成功后重定向到referer(FOSUserBundle)

时间:2016-02-12 11:51:25

标签: symfony fosuserbundle referer

我的重定向适用于注销但不适用于登录,它保留在登录页面上但是referer具有正确的值(我在登录表单中显示{{ app.request.headers.get('referer') }})。

Security.yml

firewalls:
   main:
       pattern: ^/
       form_login:
           provider:        fos_userbundle
           csrf_provider:   security.csrf.token_manager
           use_referer:     true
           success_handler: authentication_handler
       logout:
           success_handler: authentication_handler
       anonymous: true

处理程序

namespace LeJardinEbene\Bundle\Form\Handler;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;

class AuthenticationHandler implements AuthenticationSuccessHandlerInterface, LogoutSuccessHandlerInterface
{
    public function onAuthenticationSuccess(Request $request, TokenInterface $token)
    {
        $referer = $request->headers->get('referer');
        return new RedirectResponse($referer);
    }

    public function onLogoutSuccess(Request $request)
    {
        $referer = $request->headers->get('referer');
        return new RedirectResponse($referer);
    }
}

Services.yml

services:
    authentication_handler:
        class: LeJardinEbene\Bundle\Form\Handler\AuthenticationHandler

有人知道这是什么问题吗?

更新

正如你所知,我把处理程序拆分为2:

class LoginAuthenticationHandler
{
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
    //$referer = $request->headers->get('referer');
    $referer = $event->getRequest()->headers->get('referer');
    return new RedirectResponse($referer);
}
}


class LogoutAuthenticationHandler implements LogoutSuccessHandlerInterface
{
public function onLogoutSuccess(Request $request)
{
    $referer = $request->headers->get('referer');
    return new RedirectResponse($referer);
}
}


services:
login_authentication_handler:
    class: LeJardinEbene\Bundle\Form\Handler\LoginAuthenticationHandler
    tags:
        - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

logout_authentication_handler:
    class: LeJardinEbene\Bundle\Form\Handler\LogoutAuthenticationHandler

但现在我收到以下错误:

Fatal error: Uncaught exception 'Symfony\Component\Debug\Exception\ContextErrorException' with message 'Catchable Fatal Error: Argument 1 passed to Symfony\Component\Security\Http\Authentication\CustomAuthenticationSuccessHandler::__construct() must implement interface Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface, instance of LeJardinEbene\Bundle\Form\Handler\LoginAuthenticationHandler given

更新2

namespace LeJardinEbene\Bundle\Form\Handler;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;

class LoginAuthenticationHandler extends AuthenticationSuccessHandlerInterface
{
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
    $referer = $event->getRequest()->headers->get('referer');
    return new RedirectResponse($referer);
}
}

产生错误:

Fatal error: Class LeJardinEbene\Bundle\Form\Handler\LoginAuthenticationHandler cannot extend from interface Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface in /Applications/XAMPP/xamppfiles/htdocs/symfony2/src/LeJardinEbene/Bundle/Form/Handler/LoginAuthenticationHandler.php on line 22

更新3

我已经尝试了,它会导致此错误:

Fatal error: Class LeJardinEbene\Bundle\Form\Handler\LoginAuthenticationHandler contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface::onAuthenticationSuccess) in /Applications/XAMPP/xamppfiles/htdocs/symfony2/src/LeJardinEbene/Bundle/Form/Handler/LoginAuthenticationHandler.php on line 22

如果我这样做,一切都必须改变吗?我的意思是,不再是$ event等,而是$ request和$ token再次作为参数...当我打开这个主题时,它没有用,arghhhhhhhhhhh !!

更新4

services.yml

services:
login_handler:
    class: LeJardinEbene\Bundle\Form\Handler\LoginAuthenticationHandler
    tags:
        - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

security.yml

firewalls:
   main:
       pattern: ^/
       form_login:
           provider:        fos_userbundle
           csrf_provider:   security.csrf.token_manager
           use_referer:     true
           success_handler: login_handler
       logout:
           success_handler: logout_authentication_handler
       anonymous: true

2 个答案:

答案 0 :(得分:1)

尝试在AuthenticationHandler中实现以下方法:

public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) 
{
    $user = $event->getAuthenticationToken()->getUser();
}

它解决了我的问题。

<强>更新

如果添加此方法无法解决问题,请将以下内容添加到:

$referer = $event->getRequest()->headers->get('referer');

return new RedirectResponse($referer);

之后,如果事件未被触发,您应该将AuthenticationHandler分成两部分(例如LogoutSuccessHandler和AuthenticationHandler),声明两个服务并指定您正在侦听的事件,以及应该调用哪个方法。

示例:

services:
    authentication_handler:
        class: LeJardinEbene\Bundle\Form\Handler\AuthenticationHandler
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

Update2

Here a gist包括您的LoginAuthenticationHandler和相应的服务声明。

答案 1 :(得分:0)

尝试在2个处理程序中分离处理程序LeJardinEbene \ Bundle \ Form \ Handler \ AuthenticationHandler,一个实现AuthenticationSuccessHandlerInterface,另一个实现LogoutSuccessHandlerInterface。代码将是这样的:

<?php

namespace LeJardinEbene\Bundle\Form\Handler;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;

class AuthenticationHandler implements AuthenticationSuccessHandlerInterface
{
 public function onAuthenticationSuccess(Request $request, TokenInterface $token)
 {
  $referer = $request->headers->get('referer');
  return new RedirectResponse($referer);
 }
}

<?php

namespace LeJardinEbene\Bundle\Form\Handler;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;

class LogoutAuthenticationHandler implements LogoutSuccessHandlerInterface
{

 public function onLogoutSuccess(Request $request)
 {
  $referer = $request->headers->get('referer');
  return new RedirectResponse($referer);
 }
}

对不起我的英文