2016-03-04 76 views
1

如何獲得成功授權後返回的json對象,而不是重定向到默認路徑?我使用的是Symfony 3.0.1,我沒有使用FOSBundle。如何在成功授權後返回json對象而不是重定向

我的登錄控制器看起來是這樣的:

class ClientLoginController extends Controller 
{ 
    /** 
    * @Route("/login", name="login") 
    */ 
    public function loginAction(Request $request) 
    { 
     $client = new Client(); 
     $form = $this->createForm(ClientLoginType::class, $client); 

     $form->handleRequest($request); 

     $authenticationUtils = $this->get('security.authentication_utils'); 

     $lastEmail = $authenticationUtils->getLastUsername(); 

     $error = $authenticationUtils->getLastAuthenticationError(); 

     if ($form->isSubmitted() && $form->isValid()) 
     { 
      return new JsonResponse(
       array(
        'message' => 'Success! You're authorised!', 
        'result' => $this->renderView('SymfonyBundle::client/success.html.twig') 
       ), 200); 
     } 

     return $this->render(
      'SymfonyBundle::security/security.html.twig', 
      array(
       'login_form' => $form->createView(), 
       'error'   => $error, 
       'last_email' => $lastEmail, 
      ) 
     ); 
    } 
} 

而且在security.yml配置登錄部分看起來是這樣的:

form_login: 
    login_path: login 
    check_path: login 
    username_parameter: _email 
    failure_forward: false 
    default_target_path: login 
    csrf_token_generator: security.csrf.token_manager 

預先感謝您!

回答

6

當您將登錄表單發佈到安全配置中設置爲check_path的URL時,symfony將攔截偵聽器的請求並在內部處理用戶身份驗證,並根據配置重定向到頁面。因此,if ($form->isSubmitted() && $form->isValid())中的代碼將不會被實際調用。

你有多種選擇可以覆蓋這種行爲:

鏈接的blog post上面的身份驗證處理程序案件正是你需要的。我只是在這裏複製粘貼代碼,你可以在帖子中找到更多細節。

創建處理程序類:

// AuthenticationHandler.php 

namespace path\to\your\class; 

use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\Routing\RouterInterface; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 
use Symfony\Component\Security\Core\Exception\AuthenticationException; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Security\Core\SecurityContextInterface; 
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; 
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; 

class AuthenticationHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface 
{ 
    private $router; 
    private $session; 

    /** 
    * Constructor 
    * 
    * @author Joe Sexton <[email protected]> 
    * @param RouterInterface $router 
    * @param Session $session 
    */ 
    public function __construct(RouterInterface $router, Session $session) 
    { 
     $this->router = $router; 
     $this->session = $session; 
    } 

    /** 
    * onAuthenticationSuccess 
    * 
    * @author Joe Sexton <[email protected]> 
    * @param Request $request 
    * @param TokenInterface $token 
    * @return Response 
    */ 
    public function onAuthenticationSuccess(Request $request, TokenInterface $token) 
    { 
     // if AJAX login 
     if ($request->isXmlHttpRequest()) { 

      $array = array('success' => true); // data to return via JSON 
      $response = new Response(json_encode($array)); 
      $response->headers->set('Content-Type', 'application/json'); 

      return $response; 

     // if form login 
     } else { 

      if ($this->session->get('_security.main.target_path')) { 

       $url = $this->session->get('_security.main.target_path'); 

      } else { 

       $url = $this->router->generate('home_page'); 

      } // end if 

      return new RedirectResponse($url); 

     } 
    } 

    /** 
    * onAuthenticationFailure 
    * 
    * @author Joe Sexton <[email protected]> 
    * @param Request $request 
    * @param AuthenticationException $exception 
    * @return Response 
    */ 
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 
    { 
     // if AJAX login 
     if ($request->isXmlHttpRequest()) { 

      $array = array('success' => false, 'message' => $exception->getMessage()); // data to return via JSON 
      $response = new Response(json_encode($array)); 
      $response->headers->set('Content-Type', 'application/json'); 

      return $response; 

     // if form login 
     } else { 

      // set authentication exception to session 
      $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception); 

      return new RedirectResponse($this->router->generate('login_route')); 
     } 
    } 
} 

註冊爲服務,並設置是爲使用防火牆的成功和失敗的處理程序:

# Resources/config/services.yml 

acme.security.authentication_handler: 
     class: path\to\your\class\AuthenticationHandler 
     public: false 
     arguments: 
      - @router 
      - @session 

# app/config/security.yml 

security: 
    firewalls: 
     main: 
      form_login: 
       check_path:  security_check_route 
       success_handler: acme.security.authentication_handler 
       failure_handler: acme.security.authentication_handler     
+0

非常感謝您!創建一個身份驗證處理程序似乎是全面的:) – rvaliev

+0

@rvaliev如果你找到這個答案是你正在尋找的,請接受它:) – tftd

相關問題