Symfony:如何在登录时设置初始化数据

时间:2018-08-02 10:49:24

标签: symfony local-storage symfony-2.8

我面临困境和优化问题:

在我的Symfony 2.8应用程序中,我需要自定义设置和其他业务逻辑数据(从数据库表,而不是从SF参数)加载,可能需要已登录的用户在不同页面上使用。

起初,那些几乎不需要的数据,所以我仅在页面需要它时才加载它们。但是现在随着应用程序的增长,我越来越需要它们。

因此,我正在考虑在用户登录时加载它们,并由于cookie太小而将它们另存为客户端上的localStorage。

但是我不确定如何做到最好。 我有一个登录成功处理程序,可以在用户成功登录后在正确的页面上重定向。

目前我有一个:

use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;

class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
{
    protected $router;
    protected $authorizationChecker;

    public function __construct(Router $router, AuthorizationChecker $authorizationChecker)
    {
        $this->router = $router;
        $this->authorizationChecker = $authorizationChecker;
    }

    /**
     * What to do when user logs in.
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token)
    {
        $response = null;

        if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
            //an admin is redirected towards this page
            $response = new RedirectResponse($this->router->generate('my_back_admin'));
        } else if ($this->authorizationChecker->isGranted('ROLE_USER')) {
            //a user is redirected towards this page
            $response = new RedirectResponse($this->router->generate('my_back_user'));
        }
        //redirect to any last visited page if any
        $key = '_security.main.target_path';
        if ($request->getSession()->has($key)) {
            $url = $request->getSession()->get($key);
            $request->getSession()->remove($key);
            $response = new RedirectResponse($url);
        }

        return $response;
    }
}

所以我在考虑添加一个setInitialData()方法,在该方法中我可以获取所需的所有设置并修改onAuthenticationSuccess:

public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
    $response = null;
    //retrieve array of data to be set in the init  
    $toBeSaved = $this->setInitialData();

    if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
        //an admin is redirected towards this page
        $response = new RedirectResponse($this->router->generate('my_back_admin', ['initdata'=>$toBeSaved]));
    } else if ($this->authorizationChecker->isGranted('ROLE_USER')) {
        //a user is redirected towards this page
        $response = new RedirectResponse($this->router->generate('my_back_user', ['initdata'=>$toBeSaved]));
    }
    //redirect to any last visited page if any
    $key = '_security.main.target_path';
    if ($request->getSession()->has($key)) {
        $url = $request->getSession()->get($key);
        $request->getSession()->remove($key);
        $response = new RedirectResponse($url, ['initdata'=>$toBeSaved]);
    }

    return $response;
}

然后在主模板上,我将检索该数据

{% for paramName, paramValue in app.request.query %}
    {% if paramName == 'initdata' %}
    <div id="initdata" data-init="{{paramValue|json_encode}}"></div>
    {% endif %}
{% endfor %}

并添加一个类似于以下内容的javascript块:

<script>
    if ($('#initdata').length > 0){
      localStorage.removeItem('initdata');
      localStorage.setItem('initdata', JSON.stringify($('#initdata').data('init')));
    }
</script>

但是这种方法似乎不正确:我不确定这是否是最好的方法。

此外,由于这些都是通过重定向发送的,因此数据显示在查询字符串中,这是不理想的:(

1 个答案:

答案 0 :(得分:0)

这不会像通过创建多个具有相同ID = <div>的{​​{1}}元素那样具有多个参数那样有效。随后的initdata选择器将仅捕获第一个选择器(afaik)。

我看到您确实通过查询字符串发送了参数。这会照顾到多个值,但这也会在用户URL中公开您的用户设置,不是吗?如果确实如此,那么它到处都是安全漏洞。请记住,此类URL会保留在浏览器的历史记录中。

相反,我建议您创建一个单独的控制器操作jQuery,将通过/_get_user_settings AJAX进行调用。服务器将提供GET响应,您可以将其保存到JSON,而几乎没有问题。

希望这对您有帮助...