Проверьте, имеет ли пользователь доступ к определенной странице
Как я могу определить, имеет ли пользователь разрешение на доступ к определенной странице?
6 answers
Если вы хотите проверить, имеет ли текущий вошедший в систему пользователь доступ к странице, вы можете использовать следующий код:
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
. Чтобы узнать, как изменить значение глобального $user
, вы можете посмотреть , программно выдающий себя за другого пользователя не заставляя текущего вошедшего в систему пользователя выходить из системы. Разница в том, что вместо использования значения, возвращаемого из drupal_anonymous_user(), вы используете значение, возвращаемое из user_load().
Попробуйте путь drupal_valid_path().
Функция возвращает TRUE
путь, переданный в качестве аргумента, и текущий пользователь имеет к нему доступ. Итак, если вы работаете на Drupal 7 и вам нужно проверить доступ у текущего вошедшего в систему пользователя, это самый простой способ:
if (drupal_valid_path('my/path')) {
// Your code here...
}
Вызовите access callback
, указанный в пункте меню, который отвечает за страницу. Этот пункт меню обычно создается с помощью Drupal, вызывающего реализацию hook_menu
и хранится где-то в базе данных. Остерегайтесь, что данные, возвращаемые hook_menu
, могут быть изменены модулем, реализующим hook_menu_alter
.
Имейте в виду, что некоторые модули могут не передавать пользователя в качестве отдельного аргумента (как указано в клавише access arguments
пункта меню), но вместо этого могут использовать глобальный $user
вместо этого объект. Вам нужно будет проверить это для каждого используемого вами модуля.
Проверьте user_access()
функция. Смотрите ссылку для получения указанных параметров для каждой версии Drupal. Со страницы документации для Drupal 7-8:
Параметры
$строка разрешения, такого как "администрирование узлов", на наличие которого проверяется.
$учетная запись (необязательно) Учетная запись для проверки, если не указано, используется ли в настоящее время вошедший в систему пользователь.
Возвращаемое значение
Логическое значение TRUE, если текущий пользователь имеет запросил разрешение.
Все проверки разрешений в Drupal должны проходить через эту функцию. Таким образом, мы гарантируем согласованное поведение и гарантируем, что суперпользователь может выполнять все действия.
Если вам нужно знать, может ли пользователь получить доступ к определенному узлу и использует модуль доступа к узлу, вы можете использовать node_access(). (без модуля доступа к узлу им просто нужно разрешение "доступ к контенту".)
Если вы хотите выяснить, может ли пользователь получить доступ к произвольному пути, определяемому реализацией hook_menu(), вам, возможно, придется извлечь пункт меню из базы данных и оценить его параметр "обратный вызов доступа".
$node = node_load(123);
$account = user_load(456);
if (node_access("update", $node, $account) === TRUE)
{
print "access";
}