Сбой аутентификации по имени пользователя или электронной почте с DBAL Исключение: неопределенное смещение: 1 - PullRequest
0 голосов
/ 13 марта 2019

Начиная с успешной аутентификации по электронной почте (в 4.2.4), попытка выполнить User Provider docs для добавления аутентификации по имени пользователя завершается с

Исключением DBAL: ..Неопределенное смещение: 1

Любопытно, что если я запускаю инструкцию SQL, как показано в профилировщике отладки, View runnable query, запрос выполняется правильно и возвращает ненулевой результат.Поэтому, по крайней мере, хранилище может вернуть имя пользователя.

Я попытался переписать оператор построителя запросов, используя entityManager;предоставление оператора setParameters() с двумя параметрами;все безрезультатно.

Редактировать # 2:

Выдвигая код Доктрина, как указано в следе (см. ниже), исключение происходит в строке

[$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types);

$query и $params (как показано с dd(...)) имеют смысл для меня.Однако переменная $types непрозрачна: это массив [0 => 102, 1 => 102].Исключение происходит с оператором SQLParserUtils....

end Edit # 2

Edit # 3:

Вот что происходит в Doctrine, но я понятия не имею о намерениикода.В Doctrine\DBAL\SQLParserUtils строки 129 - 133 содержатся в цикле foreach (), запускаемом один раз для каждого элемента в массиве $paramsPos [0 => 496, 1 => 513], где значения - это расположение заменяемых параметров в операторе SQL.Массив $ params изначально содержит

array:2 [▼
  0 => array:1 [▼
    "username" => "gbrooks"
  ]
  1 => array:1 [▼
    "username" => "gbrooks"
  ]
]

После выполнения кода в 125 - 133 (как показано ниже)

$needle    += $paramOffset;
$needlePos += $queryOffset;
$count      = count($params[$needle]);

$params = array_merge(
    array_slice($params, 0, $needle),
    $params[$needle],
    array_slice($params, $needle + 1)
);

массив $params содержит

array:2 [▼
  "username" => "gbrooks"
  0 => array:1 [▼
    "username" => "gbrooks"
  ]
]

Обратите внимание, что больше не существует ключа 1, поэтому, когда оператор count($params[$needle]) в строке 127 встречается при следующем проходе цикла (и $needle теперь равно 1, DBAL Exception Undefined offset: 1 выбрасывается.

end Edit # 3

UserRepository:

namespace App\Repository;

use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository implements UserLoaderInterface
{
    public function loadUserByUsername($usernameOrEmail)
    {
        $user = $this->createQueryBuilder('u')
            ->where('u.username = :query OR u.email = :query')
            ->setParameter('query', $usernameOrEmail)
            ->getQuery()
            ->getOneOrNullResult();
    }
}

LoginFormAuthenticator содержит:

public function getUser($credentials, UserProviderInterface $userProvider)
{
    $token = new CsrfToken('authenticate', $credentials['csrf_token']);
    if (!$this->csrfTokenManager->isTokenValid($token)) {
        throw new InvalidCsrfTokenException();
    }

    $user = $this->entityManager->getRepository(User::class)->loadUserByUsername(['username' => $credentials['username']]);

    if (!$user) {
        // fail authentication with a custom error
        throw new CustomUserMessageAuthenticationException('Email could not be found.');
    }

    return $user;
}

Трассировка:

G:\Documents\workspace\mana\vendor\doctrine\dbal\lib\Doctrine\DBAL\DBALException.php:172 {▶}
  G:\Documents\workspace\mana\vendor\doctrine\dbal\lib\Doctrine\DBAL\DBALException.php:145 {▶}
  G:\Documents\workspace\mana\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php:911 {▶}
  G:\Documents\workspace\mana\vendor\doctrine\orm\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php:50 {▶}
  G:\Documents\workspace\mana\vendor\doctrine\orm\lib\Doctrine\ORM\Query.php:334 {▶}
  G:\Documents\workspace\mana\vendor\doctrine\orm\lib\Doctrine\ORM\AbstractQuery.php:967 {▶}
  G:\Documents\workspace\mana\vendor\doctrine\orm\lib\Doctrine\ORM\AbstractQuery.php:922 {▶}
  G:\Documents\workspace\mana\vendor\doctrine\orm\lib\Doctrine\ORM\AbstractQuery.php:765 {▶}
  G:\Documents\workspace\mana\src\Repository\UserRepository.php:24 {▶}
  G:\Documents\workspace\mana\src\Security\LoginFormAuthenticator.php:74 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-guard\Provider\GuardAuthenticationProvider.php:102 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-guard\Provider\GuardAuthenticationProvider.php:96 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-core\Authentication\AuthenticationProviderManager.php:76 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-guard\Firewall\GuardAuthenticationListener.php:130 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-guard\Firewall\GuardAuthenticationListener.php:82 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-bundle\Debug\WrappedListener.php:46 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-bundle\Debug\TraceableFirewallListener.php:35 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-http\Firewall.php:90 {▶}
  G:\Documents\workspace\mana\vendor\symfony\security-bundle\EventListener\FirewallListener.php:48 {▶}
  G:\Documents\workspace\mana\vendor\symfony\event-dispatcher\Debug\WrappedListener.php:115 {▶}
  G:\Documents\workspace\mana\vendor\symfony\event-dispatcher\EventDispatcher.php:212 {▶}
  G:\Documents\workspace\mana\vendor\symfony\event-dispatcher\EventDispatcher.php:44 {▶}
  G:\Documents\workspace\mana\vendor\symfony\event-dispatcher\Debug\TraceableEventDispatcher.php:145 {▶}
  G:\Documents\workspace\mana\vendor\symfony\http-kernel\HttpKernel.php:126 {▶}
  G:\Documents\workspace\mana\vendor\symfony\http-kernel\HttpKernel.php:67 {▶}
  G:\Documents\workspace\mana\vendor\symfony\http-kernel\Kernel.php:198 {▶}
  G:\Documents\workspace\mana\public\index.php:25 {▶}

Ответы [ 2 ]

0 голосов
/ 15 марта 2019

Вся проблема заключалась в том, что аргумент this->entityManager->getRepository(User::class)->loadUserByUsername(...) НЕ должен быть массивом, а скаляром.

Возможно, я смогу сделать бизнес, создав Алиса-подобные кроличьи норы для попадания в него.

0 голосов
/ 14 марта 2019

Обновите свой репозиторий до этого:

namespace App\Repository;

use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository implements UserLoaderInterface
{
    public function loadUserByUsername($usernameOrEmail)
    {
        return $this->createQueryBuilder('u')
            ->where('u.username = :query')
            ->orWhere('u.email = :query')
            ->setParameter('query', $usernameOrEmail)
            ->getQuery()
            ->getOneOrNullResult();
    }
}
...