加载 Web 调试工具栏时出错

Posted

技术标签:

【中文标题】加载 Web 调试工具栏时出错【英文标题】:An error occurred while loading the web debug toolbar 【发布时间】:2018-09-30 02:44:27 【问题描述】:

我正在开发 Symfony 3.4 项目,并且遇到了一个奇怪的问题。 Web 调试工具栏无法加载,而是给出错误“加载 Web 调试工具栏时发生错误。打开 Web 分析器”。这是屏幕截图

当我点击打开网络分析器链接时,它会将我带到另一个异常页面。这是它的截图

所以经过数小时的调试后,我发现问题出在 自定义监听器。它在我的 services.yml 中注册如下:

services:
    language.kernel_request_listener:
        class: TraceBundle\Listeners\LanguageListener
        arguments:
            - "@service_container"
        tags:
            -  name: kernel.event_listener, event: kernel.request, method: setLocale 

这里是 LanguageListener.php

<?php

namespace TraceBundle\Listeners;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;


class LanguageListener

    private $token_storage;

    private $securityContext;

    private $container;

    public function __construct(ContainerInterface $containerInterface)
    
        $this->container = $containerInterface;
        $this->securityContext = $this->container->get('security.authorization_checker');
        $this->token_storage = $this->container->get('security.token_storage');
    

    public function setLocale(GetResponseEvent $event)
    


        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) 
            return;
        

            if ($this->securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) 
            $user = $this->token_storage->getToken()->getUser();
            $userLocale = $user->getTenant()->getLanguage()->getValue();
            $tenantid = $this->container->get('tenant_manager')->getTenantId($user);
            $request = $event->getRequest();
            $request->attributes->set('tenantid', $tenantid);
            if ($userLocale) 
                $request->setLocale($userLocale);
                $translator = $this->container->get('translator');
                $translator->setLocale($userLocale);
            
        
    
 

现在当我评论以下几行时:

if ($this->securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) 
            $user = $this->token_storage->getToken()->getUser();
            $userLocale = $user->getTenant()->getLanguage()->getValue();
            $tenantid = $this->container->get('tenant_manager')->getTenantId($user);
            $request = $event->getRequest();
            $request->attributes->set('tenantid', $tenantid);
            if ($userLocale) 
                $request->setLocale($userLocale);
                $translator = $this->container->get('translator');
                $translator->setLocale($userLocale);
            

错误消失,分析器按预期加载。

我在每一行之后都尝试了var_dump(),所有值似乎都很好。服务tenant_manager 和翻译服务一样工作正常。我在这里想念什么?如果您需要更多代码,请告诉我。

提前致谢!

编辑:这里要求的是我的security.yml:

security:

    # https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
    providers:
        in_memory:
            memory: ~
        fos_userbundle:
            id: fos_user.user_provider.username  

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            pattern: ^/
            form_login:
                success_handler: authentication.handler.login_success_handler 
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager

#            logout:       true
            logout: 
                path:   /logout
                target: /login

            anonymous:    true        

        js_router:
            pattern: ^/(js\/routing)
            security: false

    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN


    access_control:
        -  path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY 
        -  path: ^/dashboard, role: ROLE_ADMIN 
        -  path: ^/campaigns, role: ROLE_ADMIN 
        -  path: ^/dashboard, role: ROLE_ADMIN 
        -  path: ^/lives, role: ROLE_ADMIN 
        -  path: ^/colleagues, role: ROLE_ADMIN 
        -  path: ^/addcolleague, role: ROLE_ADMIN 
        -  path: ^/adminpage, role: ROLE_ADMIN 
        -  path: ^/test, role: ROLE_ADMIN 
        -  path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY 
        -  path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY 
        -  path: ^/admin/, role: ROLE_ADMIN         

【问题讨论】:

请提供您的security.yml 代码 如果您的侦听器处理得太快,这可能是一个优先问题。您可以尝试在服务定义中设置优先级:-256。但可能不是。考虑忽略路由 _wdt 看看是否有帮助。 @Cerad 当我调试 kernek.request 监听器时,我可以看到 LanguageListener::setLocale() 方法的优先级为 0 @Pavel 我已经用 security.yml 更新了问题 并不认为优先级是问题所在。您可能会尝试的另一件事是从侦听器方法内部而不是在构造函数中获取安全上下文和令牌存储服务。但是因为您的问题似乎只发生在调试 _wdt 路由中,所以简单地忽略它应该可以工作。 【参考方案1】:

对我来说,解决方案是,当我为一个几乎干净的项目加注星标时,仍然存在这个问题: “加载 Web 调试工具栏时出错。打开 Web 分析器。”

我的解决方案: 我在公共目录中添加了一个 .htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteRule ^(.*)$ ./index.php/$1 [QSA,L]
RewriteCond %HTTP:Authorization ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

只有工具栏出现。

【讨论】:

【参考方案2】:

我在使用带有 TokenStorageInterface 的自定义侦听器时遇到了完全相同的问题。

这是我的监听器代码的缩小版本:

class DatabaseUserAuthenticationListener 
    private $authToken;

    public function __construct(TokenStorageInterface $tokenStorage) 
        if ($tokenStorage->getToken())  
            $this->authToken = $tokenStorage->getToken();
        
    

    public function onKernelController(FilterControllerEvent $event)  
        if ($this->authToken)  
            $this->authToken->setAttribute("blah", true);
        
    

就我而言,违规行是$this-&gt;authToken-&gt;setAttribute("blah", true);。当 _wdt 路由被调用时,$this-&gt;authToken 最终成为 null(因为它们没有用户上下文)。至少这是我的理论。

@Pavel 是正确的,因为 Symfony 在请求之间将令牌设置为 null,尽管我不认为是 security: false 在这样做。

在使用它之前检查您的令牌是否存在且不为空或为空 (if ($this-&gt;authToken) ...) 可以解决问题(至少对我而言)。

@utkarsh2k2,我确定您已经解决了您的问题...如果没有,您可以在调用 -&gt;getUser() 之前尝试检查 $this-&gt;token_storage-&gt;getToken() 是否有内容。

【讨论】:

【参考方案3】:

我用你的代码做了一些实验,发现了这个:

删除这些行可以解决问题:

    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false

也用这些帮助替换它们:

    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        anonymous: true

所以我可以得出结论,security: false 导致在幕后将安全令牌设置为null

到目前为止,我还没有找到这种机制(将继续尝试),因此将不胜感激。

另一种解决方案是在侦听器内部检查令牌是否不为空:

    if (null !== $this->token_storage->getToken()
        && $this->securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) 
        ...
    

但这会让你的代码关心你的开发配置(开发防火墙)引起的情况,所以我认为这不是最好的方法。

欢迎任何 cmets/添加。

【讨论】:

以上是关于加载 Web 调试工具栏时出错的主要内容,如果未能解决你的问题,请参考以下文章

Symfony Route 中断调试工具栏

GDB调试工具动态加载内存管理(day04)

Python原生调试工具pdb实践小结

按下 Chrome 调试工具旋转到横向按钮时,Angular 组件会重新加载

微信公众号web开发调试不方便吗?送你2款调试工具完美解决

小程序-解决体验版只能打开调试工具才能加载数据(请求接口)问题