【发布时间】:2023-03-29 13:41:01
【问题描述】:
我遇到了一个让我抓狂的 FOSUserBundle 错误:
我使用引导模式进行身份验证,如下所示:
<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;
}
}
非常感谢您的支持!
【问题讨论】:
-
嘿 Jérémie,我认为您应该检查 symfony 响应您的请求发送的会话 cookie 是否设置正确。 (从你所描述的 - 听起来好像没有)上次我遇到类似的问题是因为跨域请求,所以你应该确保cookie域和你使用的域匹配
-
感谢您的回复。我检查了返回的 cookie,它似乎很好(如果我与其他应用程序进行比较)。这是:REMEMBERME=SlVzZXJCdW5kbGVcRW50aXR5XFVzZXI6YW1SaGNtRjFiSFE9OjE1MTcyMTUxMDU6MWQ5YTBkNTIyZGQ1YTllNzdiNjcwZjMwMjk3NjUxN2E5YzU0YTVkYTIwMGMwMjEzZDllN expires=星期一,2018 年 1 月 29 日 08:38:25 GMT;路径=/; httponly
标签: php jquery ajax twitter-bootstrap symfony