使用Symfony2的我已经实现了AJAX的行动来管理一些书签在我的应用程序(添加/删除)。因此,用户需要被验证以继续。 我有一个解决方案,重定向用户到登录页面,但我认为这将是更好地使用一个事件来处理这个重定向。
Using Symfony2 I have implemented an AJAX action to manage some bookmarks (add/remove) in my application. So a user needs to be authenticated to proceed. I have a solution that redirects user to login page but I think it would be better to use an event to handle this redirection.
实际的解决方案:
检查用户的认证的完成同样的方式,在FOSUserBundle
Check of user's authentication is done the same way that in FOSUserBundle.
的路由的
fbn_guide_manage_bookmark:
path: /bookmark/manage
defaults: { _controller: FBNGuideBundle:Guide:managebookmark }
options:
expose: true
requirements:
_method: POST
控制器:的
public function manageBookmarkAction(Request $request)
{
if ($request->isXmlHttpRequest()) {
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
return new JsonResponse(array('status' => 'login'));
}
// DO THE STUFF
}
}
jQuery的:的
$(function() {
$('#bookmark').click(function() {
$.ajax({
type: 'POST',
url: Routing.generate('fbn_guide_manage_bookmark'),
data : xxxx, // SOME DATA
success: function(data) {
if (data.status == 'login') {
var redirect = Routing.generate('fos_user_security_login');
window.location.replace(redirect);
} else {
// DO THE STUFF
}
},
});
});
});
其他解决方案? :
为了不验证在控制器级别的用户进行身份验证,我会保护我的路线在安全配置文件:
In order not verify at controller level that user is authenticated, I would protect my route in security configuration file :
安全性:的
security:
access_control:
- { path: ^/(fr|en)/bookmark/manage, role: ROLE_USER }
控制器:的
public function manageBookmarkAction(Request $request)
{
if ($request->isXmlHttpRequest()) {
$user = $this->getUser();
// THIS VERIFCATION SHOULD NOW BE REMOVED
/*
if (!is_object($user) || !$user instanceof UserInterface) {
return new JsonResponse(array('status' => 'login'));
}
*/
// DO THE STUFF
}
}
基本上,当尝试这种解决方案,Symfony2的内部重定向吨登录页面,你可以与萤火虫看到:
Basically, when trying this solution, Symfony2 redirects internally ton login page as you can see with Firebug :
所以,我的问题是:
在不Symfony2中抛出一个事件或重新定向之前,一个异常?这将允许使用监听器来捕捉事件,并设置例如JSON响应? 在这种情况下,应该是什么样的反应prepared?类似的东西使用HTTP标头code像302(或别的什么)我的第一个解决方案。如何在AJAX一级处理呢?我可以看到一些基于异常事件的解决方案,但我想抛出异常,在控制器的水平是必要的,这正是我想避免的。下面是一个例子:
I could see some exception event solution based but I think it is necessary to throw the exception at controller level and this is what I would like to avoid. Here is an example :
https://github.com/winzou/AssoManager/blob/master/src/Asso/AMBundle/Listener/AjaxAuthenticationListener.php
推荐答案
下面是一个解决方案(见here了解详细信息):
Here is a solution (see here for details) :
安全:
firewalls:
main:
pattern: ^/
anonymous: true
provider: fos_userbundle
entry_point: fbn_user.login_entry_point
#...
access_control:
- { path: ^/(fr|en)/bookmark/manage, role: ROLE_USER }
服务:
services:
fbn_user.login_entry_point:
class: FBNUserBundleEventListenerLoginEntryPoint
arguments: [ @router ]
服务类:
namespace FBNUserBundleEventListener;
use SymfonyComponentSecurityHttpEntryPointAuthenticationEntryPointInterface;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationJsonResponse;
/**
* When the user is not authenticated at all (i.e. when the security context has no token yet),
* the firewall's entry point will be called to start() the authentication process.
*/
class LoginEntryPoint implements AuthenticationEntryPointInterface
{
protected $router;
public function __construct($router)
{
$this->router = $router;
}
/**
* This method receives the current Request object and the exception by which the exception
* listener was triggered.
*
* The method should return a Response object
*/
public function start(Request $request, AuthenticationException $authException = null)
{
if ($request->isXmlHttpRequest()) {
return new JsonResponse('',401);
}
return new RedirectResponse($this->router->generate('fos_user_security_login'));
}
}
jQuery的:
$(function() {
$('#bookmark').click(function() {
// DATA PROCESSING
$.ajax({
type: 'POST',
url: Routing.generate('fbn_guide_manage_bookmark'),
data : xxxx, // SOME DATA,
success: function(data) {
// DO THE STUFF
},
error: function(jqXHR, textStatus, errorThrown) {
switch (jqXHR.status) {
case 401:
var redirectUrl = Routing.generate('fos_user_security_login');
window.location.replace(redirectUrl);
break;
case 403: // (Invalid CSRF token for example)
// Reload page from server
window.location.reload(true);
}
},
});
});
});
相关推荐
最新文章