Access Check — сервисы с меткой access_check предоставляют различные проверки доступа.
¶Введение
Access Check используется Drupal для проверки прав доступа в различных ситуациях.
Данные сервисы тесно связаны с маршрутизацией и используются при объявлении маршрутов для контроллеров. Это основное их применение и назначение, но они могут быть использованы и за пределами маршрутизации.
¶Стандартные Access Check
Drupal ядро предоставляет следующие проверки доступа:
-
Drupal Core:
-
access_check.default(_access): Предоставляет доступ к маршруту на основе логического значения. -
access_check.entity(_entity_access): Представляет общую проверку доступа на основе сущности. В качестве значения ожидает[entity_type_id].[operation], напримерnode.update. -
access_check.entity_bundles(_entity_bundles): Предоставляет проверку что маршрут содержит сущность определенного подтипа. Напримерnode:news|page. -
access_check.entity_create(_entity_create_access): Предоставляет доступ если у пользователя есть права на создания определённой сущности. Напримерuser. -
access_check.entity_create_any(_entity_create_any_access): Предоставляет доступ если у пользователя есть права на создание любой сущности любого подтипа. Напримерnode. -
access_check.entity_delete_multiple(_entity_delete_multiple_access): Предоставляет доступ если у пользователя имеются права на массовое удаление сущности конкретного типа. Напримерnode. -
access_check.theme(_access_theme): Предоставляет доступ если у пользователя имеются права на просмотр конкретной темы оформления. -
access_check.custom(_custom_access): Предоставляет доступ на основе результата вызова функции обратного вызова указанной в качестве значения. НапримерDrupal\foo\AccessCheck::access. -
access_check.csrf(_csrf_token): Предоставляет проверку доступа на основе CSRF токена в параметрах запроса. -
access_check.header.csrf: Предоставляет проверку доступа на основе CSRF токена в заголовке запроса.
-
-
Book:
-
access_check.book.removable(_access_book_removable): Производит проверку, может ли запрошенная нода быть удалена из подшивки.
-
-
Config Translation:
-
config_translation.access.overview(_config_translation_overview_access): Производит проверку, может ли текущий пользователь получить доступ к странице обзора перевода конфигураций. -
config_translation.access.form(_config_translation_form_access): Производит проверку доступа к формам добавления, редактирования или удаления переводов.
-
-
Contact::
-
access_check.contact_personal(_access_contact_personal_tab): Производит проверку доступа к контактной странице пользователя.
-
-
Content Moderation::
-
access_check.latest_revision(_access_check.latest_revision): Производит проверки доступа к вкладке с последними ревизиями содержимого.
-
-
Content Translation::
-
content_translation.delete_access(_access_content_translation_delete): Производит проверку, может ли пользователь удалить перевод. -
content_translation.overview_access(_access_content_translation_overview): Производит проверку, может ли пользователь просматривать переводы содержимого. -
content_translation.manage_access(_access_content_translation_manage): Производит проверку, имеет ли пользователь доступ к CRUD операциям.
-
-
Field UI:
-
access_check.field_ui.view_mode(_field_ui_view_mode_access): Производит проверку, может ли пользователь настраивать отображение полей. -
access_check.field_ui.form_mode(_field_ui_form_mode_access): Производит проверку, может ли пользователь настраивать отображение формы.
-
-
JSON:API:
-
access_check.jsonapi.relationship_field_access(_jsonapi_relationship_field_access): Проверяет доступа на основе связанных маршрутов.
-
-
Layout Builder:
-
access_check.entity.layout_builder_access(_layout_builder_access): Производит проверку, может ли пользователь использовать Layout Builder.
-
-
Media:
-
access_check.media.revision(_access_media_revision): Производит проверку, может ли пользователь просматривать ревизии мультимедиа.
-
-
Node:
-
access_check.node.revision(_access_node_revision): Производит проверку, может ли пользователь просматривать ревизии содержимого. -
access_check.node.add(_node_add_access): Производит проверку, может ли пользователь просматривать страницы создания содержимого. -
access_check.node.preview(_node_preview_access): Производит проверку, может ли пользователь использовать предпросмотр содержимого.
-
-
Quickedit:
-
access_check.quickedit.entity_field(_access_quickedit_entity_field): Производит проверку, может ли пользователь редактировать конкретное поле при помощи in-place редактора.
-
-
Settings Tray:
-
access_check.settings_tray.block.has_overrides(_access_block_has_overrides_settings_tray_form): Производит проверку, может ли пользователь редактировать конкретный блок. -
access_check.settings_tray.block.settings_tray_form(_access_block_plugin_has_settings_tray_form): Производит проверку, есть ли у блока настройкаsettings_tray.
-
-
System:
-
access_check.cron(_access_system_cron): Производит проверку, может ли пользователь получить доступ к странице запуска регулярных операций. -
access_check.db_update(_access_system_update): Производит проверку, может ли пользователь использовать страницу обновления базы данных системы.
-
-
Update:
-
access_check.update.manager_access(_access_update_manager): Производит проверку, включена ли настройкаallow_authorize_operations.
-
-
User:
-
access_check.permission(_permission): Производит проверку на наличие указанных прав доступа у пользователя. -
access_check.user.register(_access_user_register): Производит проверку, может ли пользователь получить доступ к маршрутам связанными с регистрацией. -
access_check.user.role(_role): Производит проверку на наличие определённой роли(ей) у пользователя. -
access_check.user.login_status(_user_is_logged_in): Производит проверку, является ли пользователь авторизованным.
-
-
Workflows:
-
workflows.access_check.extended_permissions(_workflow_access): Производит проверку, имеет ли пользователь доступ к состояниям и переходам.
-
-
Workspaces:
-
access_check.workspaces.active_workspace(_has_active_workspace): Производит проверку, имеются ли у пользователя активные рабочие области.
-
¶Создание Access Check
Класс Access Check должен реализовывать \Drupal\Core\Routing\Access\AccessInterface и быть объявлен как сервис с меткой.
Интерфейс не выдвигает никаких требований к классу, он используется в качестве проверки, что класс является реализацией данного типа.
Класс должен (в случае использования как проверка для маршрута) реализовывать всего один метод ::access() (см. \Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass, может быть заменён при объявлении сервиса). Данный метод достаточно магический и его аргументы собираются следующим образом:
- Если это Access Check для маршрута, то он должен принимать слаги маршрута в том порядке, в котором они объявлены в пути маршрута. Например
path: '/example/{foo}/{node}'будут переданы какaccess($foo, NodeInterface $node). - Далее, вы можете принять до четырёх дополнительных аргументов в любом порядке, вы должны лишь предоставить корректные тайпхинты:
-
\Symfony\Component\HttpFoundation\Request $request -
\Symfony\Component\Routing\Route $route -
\Drupal\Core\Routing\RouteMatch $route_match -
\Drupal\Core\Session\AccountInterface $account
-
В качестве результата метод должен вернуть объект типа \Drupal\Core\Access\AccessResultInterface.
Пример разрешения доступа если ID текущего пользователя равен 17:
<?php
namespace Drupal\example\Access;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
/**
* Provides custom access check.
*/
final class UserIdAccessCheck implements AccessInterface {
/**
* A custom access check.
*
* @param \Drupal\Core\Session\AccountInterface $account
* Run access checks for this account.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function access(AccountInterface $account): AccessResult {
return AccessResult::allowedIf($account->id() == 17);
}
}Затем необходим объявить данный класс как сервис с меткой. Access Check могут опционально передавать следующие значения при объявлении сервиса:
-
applies_to: Название строки для маршрутов. При указании данной строки маршруту, данный Access Check будет подключен к нему автоматически. Если данное значение не указать, вы должны объявить методapplies(Route $route), который должен вернуть логическое значение, применим ли данный Access Check к маршруту или нет. -
method: Название метода, который будет вызван для проверки значения. По умолчаниюaccess. -
needs_incoming_request: Логичное значение, требуется ли данной проверке текущий запрос (\Symfony\Component\HttpFoundation\Request $request). Если указатьTRUE, то он будет вызываться только когда доступен объект запроса.
Пример объявления сервиса:
services:
access_check.example.user_id:
class: Drupal\example\Access\UserIdAccessCheck
tags:
- { name: access_check, applies_to: _example_user_id }
¶Использование на маршрутах
Для того чтобы использовать Access Check на маршрутах, их необходимо указать в параметре requirements с любым значением. По умолчанию, если Access Check не использует своё значение как аргумент, принято указывать 'TRUE'.
Пример подключения проверки_example_user_id при объявлении маршрута:
example.page:
path: '/example'
defaults:
_controller: '\Drupal\example\Controller\ExampleController::buildPage'
_title: 'Hello World'
requirements:
_example_user_id: 'TRUE'
¶Получение значения из маршрута
Если вы хотите дать возможность передавать примитивные значения при указании требования в маршруте, вы можете получать их из $route объекта.
Например, если вы хотите получить значение "foo bar" из _example_user_id: 'foo bar':
$route->getRequirement('_example_user_id');
¶Смотрите также
- Маршрутизация — основное применение Access Check.