Как использовать выражения в безопасности, маршрутизации, сервисах и валидации

Дата обновления перевода 2023-06-29

Как использовать выражения в безопасности, маршрутизации, сервисах и валидации

Symfony имеет мощный компонент ExpressionLanguage. Он позволяет вам добавлять высоконастраиваемую логику внутри конфигурации.

Фреймворк Symfony использует выражения сразу после установки следующими способами:

Чтобы узнать больше о том, как создавать и работать с выражениями, см. Синтаксис .

Безопасность: Сложный контроль доступа с помощью выражений

В дополнение к роли вроде ROLE_ADMIN, метод isGranted() также принимает объект Expression:

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\ExpressionLanguage\Expression;
// ...

public function indexAction()
{
    $this->denyAccessUnlessGranted(new Expression(
        '"ROLE_ADMIN" in roles or (user and user.isSuperAdmin())'
    ));

    // ...
}

В этом примере, если текущий пользователь имеет ROLE_ADMIN или если метод объекта текущего пользователя isSuperAdmin() возвращает true, тогда доступ будет разрешен (примечание: ваш объект пользователя может не иметь метода isSuperAdmin(), этот метод был придуман для данного примера).

Используется выражение, и вы можете узнать больше о синтаксисе языка выражений, см. Синтаксис .

Внутри выражения у вас есть доступ к таким переменным:

user
Объект пользователя (или строка anon, если вы не аутентифицированы).
roles
Массив ролей, которые имеет пользователь, включая иерархию ролей , но не включая атрибуты IS_AUTHENTICATED_* (см. функции ниже).
object
Объект (если он есть), который передается в качестве второго аргумента isGranted().
token
Объект метки.
trust_resolver
Объект AuthenticationTrustResolverInterface: вы скорее всего будете использовать функции is_*() ниже.

Дополнительно у вас есть доступ ко многим функциям внутри выражения:

is_authenticated
Возвращает true если пользователь аутентифицирован с помощью "запомнить меня" или аутентифицирован "полностью", т.е. возвращает "true" если пользователь "выполнил вход".
is_anonymous
Приравнивается к использованию IS_AUTHENTICATED_ANONYMOUSLY с функцией isGranted().
is_remember_me
Схоже, но не равно IS_AUTHENTICATED_REMEMBERED, см. ниже.
is_fully_authenticated
Схоже, но не равно IS_AUTHENTICATED_FULLY, см. ниже.
has_role
Проверяет, есть ли у пользователя роль - эквивалент выражения вроде 'ROLE_ADMIN' in roles.

Функции is_remember_me() и is_authenticated_fully() похожи на использование IS_AUTHENTICATED_REMEMBERED и IS_AUTHENTICATED_FULLY с функцией isGranted(), но они не одинаковы. Ниженаписанное демонстрирует отличие:

1
2
3
4
5
6
7
8
9
use Symfony\Component\ExpressionLanguage\Expression;
// ...

$ac = $this->get('security.authorization_checker');
$access1 = $ac->isGranted('IS_AUTHENTICATED_REMEMBERED');

$access2 = $ac->isGranted(new Expression(
    'is_remember_me() or is_fully_authenticated()'
));

Здесь, $access1 м $access2 будут иметь одинаковое значениe. В отличие от поведения IS_AUTHENTICATED_REMEMBERED и IS_AUTHENTICATED_FULLY, функция is_remember_me() возвращает "true" только если пользователь аутентифицирован с помощью cookie "запомнить меня", а is_fully_authenticated возвращает "true" только если пользователь действительно выполнил вход в течение этой сессии (т.е. является полноценным).