Symfony 2 FOS 用户捆绑引导模式 AJAX 登录
Posted
技术标签:
【中文标题】Symfony 2 FOS 用户捆绑引导模式 AJAX 登录【英文标题】:Symfony 2 FOS User Bundle Bootstrap modal AJAX Login 【发布时间】:2013-10-27 01:38:31 【问题描述】:是否有人已经使用 Symfony 2 和 FOS User Bundle 在 Bootstrap 模式中构建了登录表单?
这是我现在拥有的:
src/Webibli/UserBundle/Resources/config/service.yml
authentication_handler:
class: Webibli\UserBundle\Handler\AuthenticationHandler
arguments: [@router, @security.context, @fos_user.user_manager, @service_container]
app/config/security.yml
form_login:
provider: fos_userbundle
success_handler: authentication_handler
failure_handler: authentication_handler
src/Webibli/UserBundle/Handler/AuthenticationHandler.php
<?php
namespace Webibli\UserBundle\Handler;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class AuthenticationHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface
protected $router;
protected $security;
protected $userManager;
protected $service_container;
public function __construct(RouterInterface $router, SecurityContext $security, $userManager, $service_container)
$this->router = $router;
$this->security = $security;
$this->userManager = $userManager;
$this->service_container = $service_container;
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
if ($request->isXmlHttpRequest())
$result = array('success' => true);
$response = new Response(json_encode($result));
$response->headers->set('Content-Type', 'application/json');
return $response;
else
// Create a flash message with the authentication error message
$request->getSession()->getFlashBag()->set('error', $exception->getMessage());
$url = $this->router->generate('fos_user_security_login');
return new RedirectResponse($url);
return new RedirectResponse($this->router->generate('anag_new'));
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
if ($request->isXmlHttpRequest())
$result = array('success' => false, 'message' => $exception->getMessage());
$response = new Response(json_encode($result));
$response->headers->set('Content-Type', 'application/json');
return $response;
return new Response();
这是我正在加载到 Bootstrap 模式中的 Twig 视图:
% extends 'UserBundle::layout.html.twig' %
% trans_default_domain 'FOSUserBundle' %
% block user_content %
<script>
$('#_submit').click(function(e)
e.preventDefault();
$.ajax(
type : $('form').attr( 'method' ),
url : $('form').attr( 'action' ),
data : $('form').serialize(),
success : function(data, status, object)
console.log( status );
console.log( object.responseText );
);
);
</script>
<div class="modal-dialog">
<div class="modal-content">
<form action=" path("fos_user_security_check") " method="post" role="form" data-async data-target="#rating-modal" class="text-left">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title"> 'layout.login'|trans </h4>
</div>
<div class="modal-body">
% if error %
<div> error|trans </div>
% endif %
<input type="hidden" name="_csrf_token" value=" csrf_token " />
<div class="form-group container">
<label for="email"> 'security.login.username_email'|trans </label>
<input type="text" class="form-control" id="username" name="_username" value=" last_username " required="required" placeholder="adresse@email.com">
</div>
<div class="form-group container">
<label for="password"> 'security.login.password'|trans </label><br />
<input type="password" id="password" name="_password" required="required" class="form-control" placeholder="********">
</div>
<div class="form-group container">
<label for="remember_me">
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
'security.login.remember_me'|trans
</label>
</div>
</div>
<div class="modal-footer">
<input type="submit" id="_submit" name="_submit" value=" 'security.login.submit'|trans " class="btn btn-primary">
</div>
</form>
</div>
</div>
% endblock %
登录表单在没有 AJAX 的情况下工作得非常好。如果出现问题,我只是试图在模式中的表单上出现错误,或者如果登录成功则重定向用户。
谁能解释一下如何做到这一点?
【问题讨论】:
AJAX 什么时候不起作用,你可以尝试实现错误回调,看看你从服务器得到什么响应,如果有的话。 我总是成功,因为请求正在工作,但登录不成功,我不知道如何让 Symfony 返回 JSON 中的错误消息而不是 Flash 消息。目前,AJAX 调用的响应始终是一个完整的 HTML 页面,这很烦人,因为我只想要应该进入模式的内容。 【参考方案1】:我找到了解决方案。这是我添加到我的 javascript 中的内容,
<script>
$(document).ready(function()
$('#_submit').click(function(e)
e.preventDefault();
$.ajax(
type : $('form').attr( 'method' ),
url : ' path("fos_user_security_check") ',
data : $('form').serialize(),
dataType : "json",
success : function(data, status, object)
if(data.error) $('.error').html(data.message);
,
error: function(data, status, object)
console.log(data.message);
);
);
);
</script>
这是我的处理程序中的onAuthenticationFailure
方法,
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
$result = array(
'success' => false,
'function' => 'onAuthenticationFailure',
'error' => true,
'message' => $this->translator->trans($exception->getMessage(), array(), 'FOSUserBundle')
);
$response = new Response(json_encode($result));
$response->headers->set('Content-Type', 'application/json');
return $response;
我认为是我的 Ajax 方法中的 URL 错误。谢谢你的建议。
【讨论】:
【参考方案2】:我猜你要找的是这个:Symfony2 ajax login。
你的 javascript 看起来会……像这样:
$('#_submit').click(function(e)
e.preventDefault();
$.ajax(
type : $('form').attr( 'method' ),
url : $('form').attr( 'action' ),
data : $('form').serialize(),
success : function(data, status, object)
if (data.sucess == false)
$('.modal-body').prepend('<div />').html(data.message);
else
window.location.href = data.targetUrl;
);
您还必须修改 onAuthenticationSuccess-Method 的 isXmlHttpRequest-部分:
[...]
if ($request->isXmlHttpRequest())
$targetUrl = $request->getSession()->get('_security.target_path');
$result = array('success' => true, 'targetUrl' => targetUrl );
$response = new Response(json_encode($result));
$response->headers->set('Content-Type', 'application/json');
return $response;
[...]
【讨论】:
似乎是一个好的开始。我试过你的实现,唯一的问题是我总是成功地使用“真”值,从不假...... 很好 :) 你介意将我的答案标记为解决方案吗?以上是关于Symfony 2 FOS 用户捆绑引导模式 AJAX 登录的主要内容,如果未能解决你的问题,请参考以下文章
Symfony2 - 安装了 FOS 用户包的自定义身份验证提供程序