Как вернуть дополнительную информацию от избирателя в Symfony4?

У меня есть избиратель, которого я использую, чтобы проверить, может ли текущий пользователь получить доступ к объекту. В доступе может быть отказано по нескольким причинам, и я хотел бы знать, какая именно в Контроллере. Однако избиратель может вернуть только логическое значение, то же самое для isGranted() в контроллере, поэтому я не уверен, по какому каналу я могу передать нужную мне дополнительную информацию. Выброс исключения не годится, так как могут быть другие избиратели, которые еще не были вызваны.

Более близкая вещь, о которой я могу думать, - это флэш-сообщения, которые можно использовать для передачи информации вне аргументов функции и возвращаемых значений, но использовать их в этой ситуации кажется хакерством.

2 ответа

Решение

Вы можете зарегистрировать их в службе, как в LoggerInterface, но в свою собственную простую службу сбора данных.

В контейнерных сервисах Symfony по умолчанию используются "синглтоны" - одна и та же служба, полученная из нескольких мест, является одним и тем же объектом (например, регистратором). Создание простого сервиса для сбора информации можно будет изучить позже.

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

<?php
class ServiceName
{
    private $requestStack;
    public function __construct(RequestStack $requestStack) {
        $this->requestStack = $requestStack;
        $requestStack->getCurrentRequest()->attributes->set('simple-store', 'blah');
        //OR, set it in a method that is called deep in the system
    }

// And now in a controller
// $value = $request->attributes->get('simple store'),
// Or in Twig template: `{{ dump(app.request.get('simple store')) }}`:

Однако ваша собственная "служба сбора причин", вероятно, будет чище.

Что я сделал, так этоthrow new AccessDeniedHttpException('reason');непосредственно от избирателя.

Я работаю так же, как symfony илиdenyUnlessGranted()выдает такое же исключение, если избиратель возвращает false.

Но есть недостатки:

  • это заставляет вас использоватьunanimousстратегия
  • избиратели не отображаются в профилировщике, на вкладке Безопасность > Решение о доступе.
Другие вопросы по тегам