Произошла ошибка при загрузке веб-панели отладки
Я работаю над проектом Symfony 3.4 и столкнулся со странной проблемой. Панель инструментов веб-отладки не загружается и вместо этого выдает ошибку "Произошла ошибка при загрузке панели инструментов веб-отладки. Откройте веб-профилировщик". Вот скриншот
И когда я нажимаю на ссылку Открыть веб-профилировщик, я перехожу на другую страницу исключений. Вот его скриншот
Таким образом, после нескольких часов отладки я смог выяснить, что проблема находится в пользовательском слушателе. Он зарегистрирован в моем 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 }
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->authToken->setAttribute("blah", true);
, $this->authToken
в конечном итоге null
когда _wdt
маршруты называются (так как они не имеют пользовательского контекста). По крайней мере, это моя теория.
@Pavel верен в том, что Symfony устанавливает токен равным нулю между запросами, хотя я не думаю, что это security: false
это делает это
Проверка того, что ваш токен существует и не является нулевым или пустым, прежде чем работать с ним (if ($this->authToken) {...}
) исправляет проблему (по крайней мере для меня).
@ utkarsh2k2, я уверен, что вы уже исправили свою проблему... если нет, вы можете попробовать проверить это $this->token_storage->getToken()
есть что-то перед звонком ->getUser()
,
Я провел несколько экспериментов с вашим кодом и нашел это:
Удаление этих строк решает проблему:
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 (dev firewall), поэтому я решил, что это не лучший способ.
Любые комментарии / дополнения приветствуются.
Решение для меня заключалось в том, что когда я запускал почти чистый проект, проблема все еще была: "Произошла ошибка при загрузке панели инструментов веб-отладки. Откройте веб-профилировщик".
Мое решение: я добавил.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]
При этом появляется только панель инструментов.