加载Web调试工具栏时发生错误

时间:2018-04-19 14:34:32

标签: symfony symfony-3.4

我正在研究Symfony 3.4项目,并且一直面临着一个奇怪的问题。 Web调试工具栏无法加载,而是出现错误"加载Web调试工具栏时出错。打开Web Profiler。"这是截图 enter image description here

当我点击打开网页探查器链接时,它会转到另一个异常页面。这是它的截图

enter image description here

因此,经过数小时的调试后,我能够发现问题出在了  自定义监听器。它在我的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 }        

3 个答案:

答案 0 :(得分:1)

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

删除这些行解决了这个问题:

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

但是它使你的代码关心你的dev config(开发防火墙)造成的情况,所以我认为这不是最好的方法。

欢迎任何评论/补充。

答案 1 :(得分:1)

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

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

使用令牌(if ($this->authToken) {...})之前检查令牌是否存在且不为null或为空(至少对我来说)。

@ utkarsh2k2,我确定您已经解决了问题……如果没有,您可以在致电$this->token_storage->getToken()之前尝试检查->getUser()中是否有东西。

答案 2 :(得分:0)

对我来说,解决方案是,当我给一个几乎干净的proyect做星时,仍然会遇到这个问题: “加载Web调试工具栏时发生错误。打开Web Profiler。

我的解决方案: 我在公共目录中添加了.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]

只有工具栏出现。