Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony:如何在登录时设置init数据_Symfony_Local Storage_Symfony 2.8 - Fatal编程技术网

Symfony:如何在登录时设置init数据

Symfony:如何在登录时设置init数据,symfony,local-storage,symfony-2.8,Symfony,Local Storage,Symfony 2.8,我面临一个难题和一个优化问题: 在我的Symfony 2.8应用程序中,我有自定义设置和其他要加载的业务逻辑数据(来自数据库表,而不是来自SF参数),登录用户可能需要在不同页面上使用这些数据 起初,这些数据几乎不需要,所以我只在页面需要时才加载它们。但现在随着应用程序的增长,我更需要它们 所以我考虑在用户登录时加载它们,并将它们保存为客户端的本地存储,因为cookie太小了 但我不知道怎样才能最好地做到这一点。 我有一个登录成功处理程序,它允许在用户成功登录时重定向到正确的页面 目前我有一个:

我面临一个难题和一个优化问题:

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

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

所以我考虑在用户登录时加载它们,并将它们保存为客户端的本地存储,因为cookie太小了

但我不知道怎样才能最好地做到这一点。 我有一个登录成功处理程序,它允许在用户成功登录时重定向到正确的页面

目前我有一个:

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 %}
{%app.request.query%}
{%if paramName='initdata%}
{%endif%}
{%endfor%}
并添加一个javascript块,如下所示:

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

如果($('#initdata')。长度>0){
localStorage.removietem('initdata');
localStorage.setItem('initdata',JSON.stringify($('initdata').data('init'));
}
但这种方法似乎并不正确:我不确定这是最好的方法

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

这不会像通过使用多个参数创建多个具有相同ID的
元素那样飞行。后续的
jQuery
选择器将只捕获第一个(afaik)

我看到你确实是通过查询字符串发送参数的。这会考虑多个值,但这也会暴露你在用户URL中的用户设置,不是吗?如果是这样,它的安全漏洞无处不在。请记住,这样的URL会保留在浏览器的历史记录中

相反,我建议您创建一个单独的控制器操作
/\u get\u user\u settings
,您将通过
AJAX
get
调用它。服务器将提供
JSON
响应,您可以将其保存到
localStorage
中,几乎没有问题


希望这有助于…

Step停止在服务器端渲染数据,采用javascript并使用异步ajax调用加载资源。您粘贴的整个代码设计过度,无法维护且不稳定。我不确定“多div”是什么意思。我确实有多个参数,但它们都是initdata的子参数,在onAuthenticationSuccess方法中设置。因此,即使发送了其他参数,我也只对这一个感兴趣,因此只创建了一个div。也就是说,使用ajax调用的想法可能很有趣:我只能将initdata设置为true,如果如果设置了,我可以调用ajax来检索我需要的初始数据。在这种情况下,问题是:如果用户在数据正确保存之前更改页面该怎么办。同意,您需要一种方法来阻止导航,直到浏览器接收到用户设置。这通常非常快,但从好的方面来说,您的建议允许分离任务:让该方法管理重定向,并让另一个方法处理数据