使用 Symfony2,我实现了 AJAX 操作来管理应用程序中的一些书签(添加/删除)。因此,用户需要经过身份验证才能继续。 我有一个将用户重定向到登录页面的解决方案,但我认为最好使用事件来处理此重定向。
实际解决方案:
用户身份验证的检查与 FOSUserBundle 中的方式相同。
路由:
fbn_guide_manage_bookmark:
path: /bookmark/manage
defaults: { _controller: FBNGuideBundle:Guide:managebookmark }
options:
expose: true
requirements:
_method: POST
Controller :
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
}
},
});
});
});
其他解决方案? :
为了不在 Controller 级别验证用户是否已通过身份验证,我将在安全配置文件中保护我的路由:
安全:
security:
access_control:
- { path: ^/(fr|en)/bookmark/manage, role: ROLE_USER }
Controller :
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 会在内部重定向 ton 登录页面,正如您在 Firebug 中看到的那样:
所以我的问题是:
- Symfony2 在重定向之前是否抛出事件或异常?例如,这将允许使用监听器来捕获事件并设置 JSON 响应?
- 在这种情况下,应该准备什么样的应对措施?就像我的第一个使用 HTTP header 代码(如 302(或其他代码))的解决方案。如何在 AJAX 级别处理这个问题?
我可以看到一些基于异常事件的解决方案,但我认为有必要在 Controller 级别抛出异常,这是我想避免的。这是一个例子:
最佳答案
这是一个解决方案(有关详细信息,请参阅 here):
安全:
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: FBN\UserBundle\EventListener\LoginEntryPoint
arguments: [ @router ]
服务等级:
namespace FBN\UserBundle\EventListener;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* 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);
}
},
});
});
});
关于jquery - Symfony2 : AJAX request : How to handle authentication when needed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31378199/