加载 Web 调试工具栏时出错

An error occurred while loading the web debug toolbar

我正在处理 Symfony 3.4 项目,并且遇到了一个奇怪的问题。 Web 调试工具栏无法加载,而是给出错误 "An error occurred while loading the web debug toolbar. Open the web profiler." 这是屏幕截图

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

经过几个小时的调试,我发现问题出在 自定义侦听器。在我的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 }        

我对您的代码进行了一些实验并发现:

删除这些行解决了问题:

    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')) {
        ...
    }

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

欢迎任何comments/additions。

我在使用带有 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->authToken->setAttribute("blah", true);。当调用 _wdt 路由时,$this->authToken 最终成为 null(因为它们没有用户上下文)。至少那是我的理论。

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

在使用它之前检查您的令牌是否存在并且不为 null 或空 (if ($this->authToken) {...}) 解决了问题(至少对我而言)。

@utkarsh2k2,我确定你已经解决了你的问题...如果没有,你可以尝试在调用 ->getUser().

之前检查 $this->token_storage->getToken() 中是否有内容

我的解决方案是,当我为一个几乎干净的项目加注星标时仍然有这个问题: "An error occurred while loading the web debug toolbar. Open the web profiler."

我的解决方案: 我在 public 目录

中添加了一个 .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ ./index.php/ [QSA,L]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

只有工具栏出现。