Как я могу определить, есть ли у пользователя разрешение на доступ к определенной странице?
Как я могу определить, есть ли у пользователя разрешение на доступ к определенной странице?
Ответы:
Если вы хотите проверить, есть ли у вошедшего в систему пользователя доступ к странице, вы можете использовать следующий код:
if ($router_item = menu_get_item($path)) {
if ($router_item['access']) {
// The user has access to the page in $path.
}
}
$path
это путь к странице, которую вы хотите проверить (например, узел / 1, администратор / пользователь / пользователь).
Код работает в Drupal 6 и более поздних версиях, и он используется из menu_execute_active_handler () .
Причина, по которой я не предлагаю напрямую вызывать обратный вызов доступа, заключается в том, что аргументы, которые необходимо передать этой функции.
Код, используемый _menu_check_access (), следующий (Drupal 7):
$arguments = menu_unserialize($item['access_arguments'], $map);
// As call_user_func_array is quite slow and user_access is a very common
// callback, it is worth making a special case for it.
if ($callback == 'user_access') {
$item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
}
elseif (function_exists($callback)) {
$item['access'] = call_user_func_array($callback, $arguments);
}
Код, который должен быть как можно более универсальным, напрямую не обрабатывает пользовательский объект. Это означает, что невозможно заменить объект пользователя для текущего пользователя, вошедшего в систему, другим объектом пользователя.
Код должен быть достаточно универсальным для обработки определений меню, таких как следующие:
$items['node/add/' . $type_url_str] = array(
'title' => $type->name,
'title callback' => 'check_plain',
'page callback' => 'node_add',
'page arguments' => array($type->type),
'access callback' => 'node_access',
'access arguments' => array('create', $type->type),
'description' => $type->description,
'file' => 'node.pages.inc',
);
$items['node/%node'] = array(
'title callback' => 'node_page_title',
'title arguments' => array(1),
// The page callback also invokes drupal_set_title() in case
// the menu router's title is overridden by a menu link.
'page callback' => 'node_page_view',
'page arguments' => array(1),
'access callback' => 'node_access',
'access arguments' => array('view', 1),
);
В обоих определениях аргументы доступа не включают объект пользователя, и в этом случае node_access () использует объект пользователя для текущего пользователя, вошедшего в систему. Во втором случае одним из аргументов является объект узла, полученный из URL; например, если URL-адрес example.com/node/1, то второй аргумент, переданный обратному вызову доступа, является объектом узла для узла с идентификатором узла, равным 1.
Написание кода, который обрабатывает эти случаи, также будет означать дублирование кода уже существует в Drupal. Даже если вы продублировали этот код, все равно будет проблема обратных вызовов доступа, которые проверяют доступ по отношению к вошедшему в данный момент пользователю.
Если вы хотите проверить, может ли пользователь, не являющийся в данный момент вошедшим в систему пользователем, получить доступ к меню, сначала измените значение глобальной переменной $user
, используйте код, который я сообщил в начале моего ответа, а затем восстановите значение $user
, Чтобы узнать, как изменить значение global $user
, вы можете увидеть, как программно выдает себя за другого пользователя, не вызывая текущего пользователя, вошедшего в систему . Разница в том, что вместо использования значения, возвращаемого от drupal_anonymous_user () , вы используете значение, возвращаемое из user_load () .
Попробуйте drupal_valid_path () .
Функция возвращает TRUE
путь, переданный в качестве аргумента, и текущий пользователь имеет к нему доступ. Итак, если вы работаете над Drupal 7 и вам нужно проверить доступ к текущему вошедшему в систему пользователю, это самый простой способ:
if (drupal_valid_path('my/path')) {
// Your code here...
}
drupal_valid_path
отлично справляется со своей задачей и делает это именно для этого. Он использует menu_get_item и также проверяет доступ.
drupal_valid_path
это не поможет.
\Drupal::service('path.validator')->isValid($path);
- см. Документацию
Вызовите тот, access callback
который указан в пункте меню, который отвечает за страницу. Этот пункт меню обычно создается Drupal, вызывающим реализацию, hook_menu
и сохраняется где-то в базе данных. Помните, что возвращаемые данные hook_menu
могут быть изменены модулем реализации hook_menu_alter
.
Помните, что некоторые модули могут не передавать пользователя в качестве отдельного аргумента (как указано access arguments
ключом пункта меню), но вместо этого могут использовать глобальный $user
объект. Вы должны будете проверить это для каждого модуля, который вы используете.
Проверьте user_access()
функцию. Смотрите ссылку на указанные параметры для каждой версии Drupal. Со страницы документации для Drupal 7-8:
параметры
$ string Разрешение, такое как «администрировать узлы», проверяется на наличие.
$ account (необязательно) Аккаунт, который нужно проверить, если не указан, использовать вошедшего в систему пользователя.
Возвращаемое значение
Boolean TRUE, если текущий пользователь имеет запрошенное разрешение.
Все проверки прав доступа в Drupal должны проходить через эту функцию. Таким образом, мы гарантируем согласованное поведение и гарантируем, что суперпользователь может выполнять все действия.
user_access()
не всегда обратный вызов доступа, используемый меню; даже если бы это было так, вы должны знать аргументы доступа, которые вам нужно передать user_access()
.
user_access()
, просто решил, что у ОП есть разрешение проверить, есть ли у пользователя доступ. Не очень описательный вопрос
Если вам нужно знать, может ли пользователь получить доступ к определенному узлу и использует ли модуль доступа к узлу, вы можете использовать node_access () . (без модуля доступа к узлу им просто нужно разрешение «доступ к содержимому».)
Если вы хотите выяснить, может ли пользователь получить доступ к произвольному пути, который определен реализацией hook_menu (), вам, возможно, придется извлечь пункт меню из базы данных и оценить его параметр «обратный вызов доступа».
$node = node_load(123);
$account = user_load(456);
if (node_access("update", $node, $account) === TRUE)
{
print "access";
}