如何改变默认的目标路径之行为

3.4 版本
维护中的版本

默认时,Security组件会把上一次请求的URI中的信息保存在一个名为 _security.main.target_path 的session变量中(其中的 main 是firewall的名称,它在 security.yml 被定义)。登录成功后,用户会被重定向到这个路径,也就是帮助他们访问已知的最后一次请求过的页面。

在某些情况下,这并不完美。例如,当最后一次请求的URI是一个XMLHttpRequest时,返回的是非HTML或部分HTML的响应,用户被重定向到了一个“浏览器无法渲染”的页面。

为了绕过这种行为,你只需要继承 ExceptionListener 类,并覆写名为 setTargetPath() 的方法。

首先,在配置文件中覆写 security.exception_listener.class 参数(parameter)。可以在你的主力配置文件(app/config)中完成,或者从导入进来的“bundle的配置文件”中进行配置。

1
2
3
4
# app/config/services.yml
parameters:
    # ...
    security.exception_listener.class: AppBundle\Security\Firewall\ExceptionListener
1
2
3
4
5
<!-- app/config/services.xml -->
<parameters>
    <!-- ... -->
    <parameter key="security.exception_listener.class">AppBundle\Security\Firewall\ExceptionListener</parameter>
</parameters>
1
2
3
// app/config/services.php
// ...
$container->setParameter('security.exception_listener.class', 'AppBundle\Security\Firewall\ExceptionListener');

接下来,创建你自己的 ExceptionListener:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/AppBundle/Security/Firewall/ExceptionListener.php
namespace AppBundle\Security\Firewall;
 
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Firewall\ExceptionListener as BaseExceptionListener;
 
class ExceptionListener extends BaseExceptionListener
{
    protected function setTargetPath(Request $request)
    {
        // Do not save target path for XHR requests
        // You can add any more logic here you want
        // Note that non-GET requests are already ignored
        // 不去存储 XHR请求 的target path
        // 你可以添加更多逻辑。注意 非GET请求 已被忽略
        if ($request->isXmlHttpRequest()) {
            return;
        }
 
        parent::setTargetPath($request);
    }
}

你可以随需添加或多或少的逻辑!

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)