[Symfony] [FOSUserBundle]来自bootstrap modal / Lost Session

时间:2018-01-27 16:16:43

标签: php jquery ajax twitter-bootstrap symfony

我遇到了一个让我疯狂的FOSUserBundle的错误:

我使用bootstrap模式进行身份验证,如下所示:

<div class="modal fade" id="modalLogin" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-body"></div>
        </div>
    </div>
</div>

我使用链接到FOS登录URL(fos_user_security_login)的Ajax请求加载模态体:

$(".connectModal").bind("click", function() {
$.ajax({
    url: $('#path_login').val(),
    success: function (data) {
        $('#modalLogin .modal-body').html(data);
        $('#modalLogin').modal()
    }
});

});

然后,在我的模态中,我使用Ajax来检查身份验证。所以我用:

$('#form_login').submit( function(e) {
      e.preventDefault();
      e.stopImmediatePropagation();
      $.ajax({
          url: {{ path("fos_user_security_check") }},
          type: "post",
          data: {_csrf_token: $('#csrf_token').val(), _username: $('#username').val(), _password: $('#password').val(), _remember_me: 'on'},
          dataType: 'json',
          complete: function (data, statut) {
              if (statut == 'success') {
                  $('#modalLogin').modal('hide');
              }
          },
          error : function(resultat, statut, error){
              $('#error_message').text(JSON.parse(resultat.responseText).message);
              $('#error_block').show();
          }
      });
  });

一切都很棒!如果身份验证失败,我会收到错误并显示它。如果身份验证没问题,我会让用户进入Symfony会话(我可以在Symfony的调试控制台中查看)。

但是一旦我关闭我的模态,经过身份验证的用户就不会在网站的会话中传播(有不同的会话吗?!?)。我留在匿名状态...... :( 我真的不在哪里调查......这是Symfony的问题吗? FOSUserBundle? JQuery的?

要完成,这是我的安全防火墙:

profil:
        pattern: ^/account/
        security: true
        provider: fos_userbundle
        context: _security_login
        form_login:
            login_path: fos_user_security_login
            check_path: fos_user_security_check
            csrf_token_generator: security.csrf.token_manager
            success_handler: juser.success_handler
            failure_handler: juser.failure_handler
            default_target_path: /account
        logout:
            path: fos_user_security_logout
            target: /
        remember_me:
            key: "%secret%"
            lifetime: 86400

我的成功处理程序:

    <?php

namespace JUserBundle\Handler;


use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\Response;

class AuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler
{
    /**
     * Router
     * @var \Symfony\Component\Routing\RouterInterface
     */
    private $router;

    /**
     * Translator
     * @var \Symfony\Component\Translation\TranslatorInterface
     */
    private $translator;

    /**
     * AuthenticationSuccessHandler constructor.
     * @param HttpUtils $httputils
     * @param RouterInterface $router
     * @param TranslatorInterface $translator
     */
    public function __construct(HttpUtils $httputils, RouterInterface $router, TranslatorInterface $translator)
    {
        parent::__construct($httputils);

        $this->router = $router;
        $this->translator = $translator;
    }

    /**
     * Callback sur l'authentification réussie
     * @param Request $request
     * @param TokenInterface $token
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
        if($request->isXmlHttpRequest()){
            $data = array(
                'success'=> 1,
                'url' => $this->router->generate('fos_user_profile_show')
            );

            return new JsonResponse($data);
        }else{
            return parent::onAuthenticationSuccess($request, $token);
        }
    }

    /**
     * Définit le traducteur
     * @param \Symfony\Component\Translation\TranslatorInterface $translator
     */
    function setTranslator(TranslatorInterface $translator) {
        $this->translator = $translator;
    }
}

我的失败处理程序:

    <?php

namespace JUserBundle\Handler;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\RouterInterface;

class AuthenticationFailureHandler extends DefaultAuthenticationFailureHandler
{
    /**
     * Router
     * @var \Symfony\Component\Routing\RouterInterface
     */
    private $router;

    /**
     * Translator
     * @var \Symfony\Component\Translation\TranslatorInterface
     */
    private $translator;

    /**
     * AuthenticationFailureHandler constructor.
     * @param HttpKernelInterface $httpKernel
     * @param HttpUtils $httputils
     * @param RouterInterface $router
     * @param TranslatorInterface $translator
     */
    public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httputils, RouterInterface $router, TranslatorInterface $translator)
    {
        parent::__construct($httpKernel, $httputils);

        $this->router = $router;
        $this->translator = $translator;
    }

    /**
     * Callback sur l'authentification échouée
     * @param Request $request
     * @param AuthenticationException $exception
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
        if($request->isXmlHttpRequest()){
            $message = $exception->getMessageKey();
            $messageTrans = $this->translator->trans($message,array(),'FOSUserBundle');
            if($messageTrans === $message){
                $messageTrans = $this->translator->trans($message,array(),'security');
            }
            $data = array(
                'message' => $messageTrans,
            );

            return new JsonResponse($data,401);
        }else{
            return parent::onAuthenticationFailure($request, $exception);
        }
    }

    /**
     * Définit le traducteur
     * @param \Symfony\Component\Translation\TranslatorInterface $translator
     */
    function setTranslator(TranslatorInterface $translator) {
        $this->translator = $translator;
    }
}

非常感谢您的支持!

1 个答案:

答案 0 :(得分:0)

对于遇到同样问题的人,我终于找到了问题的答案。 我使用/ account。

为我的所有FOSUserBundle路线添加了前缀

结果是生成的cookie与我尝试登录的域名不对应,即为mydomain / account而不是mydomain生成cookie ...

所以我删除了路由前缀并因此修改了我的防火墙。