Проверьте, имеет ли пользователь доступ к определенной странице

Как определить, имеет ли пользователь разрешение на доступ к определенной странице?

23 голоса | спросил farzan 27 J0000006Europe/Moscow 2011, 18:37:29

6 ответов


25

Если вы хотите проверить, имеет ли пользователь, который в настоящее время вошел в систему, доступ к странице, вы можете использовать следующий код:

if ($router_item = menu_get_item($path)) {
  if ($router_item['access']) {
    // The user has access to the page in $path.
  }
}

$path - это путь к странице, которую вы хотите проверить (например, node /1, admin /user /user).

Код работает в версиях 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 () .

ответил kiamlaluno 28 J0000006Europe/Moscow 2011, 05:15:47
14

Попробуйте drupal_valid_path () .

Функция возвращает TRUE - это путь, переданный как аргумент, и текущий пользователь имеет к нему доступ. Итак, если вы работаете с Drupal 7, и вам нужно проверить доступ к текущему пользователю, то это самый простой способ:

if (drupal_valid_path('my/path')) {
  // Your code here...
}
ответил peterpoe 14 32012vEurope/Moscow11bEurope/MoscowWed, 14 Nov 2012 20:21:34 +0400 2012, 20:21:34
3

Вызвать access callback, который указан в записи меню, которая отвечает за страницу. Эта запись меню обычно создается Drupal, вызывающей реализацию hook_menu и хранится где-то в базе данных. Помните, что данные, возвращаемые hook_menu, могут быть изменены модулем, реализующим hook_menu_alter .

Остерегайтесь того, что некоторые модули могут не передавать пользователя в виде отдельного аргумента (как указано ключом ), но вместо этого можно использовать глобальный access arguments. Вам нужно будет проверить это для каждого используемого модуля.

ответил Oswald 27 J0000006Europe/Moscow 2011, 23:34:56
2

Просмотрите user_access() . См. Ссылку для указанных параметров для каждой версии Drupal. На странице документации для Drupal 7-8:

  

Параметры

     

$ string Разрешено, например, «администрировать узлы».

     

$ account (необязательно) Учетная запись, если она не указана, используется в настоящее время во время входа в систему.

     

Возвращаемое значение

     

Логическое значение ИСТИНА, если текущий пользователь имеет   запрошенное разрешение.

     

Все проверки разрешений в Drupal должны   выполните эту функцию. Таким образом, мы   гарантируют согласованное поведение и   убедитесь, что суперпользователь может выполнить   все действия.

ответил Laxman13 27 J0000006Europe/Moscow 2011, 18:49:55
2

Если вам нужно знать, может ли пользователь получить доступ к определенному узлу и использовать модуль доступа к узлу, вы можете использовать node_access () . (без модуля доступа к узлу им просто нужно разрешение «доступ к контенту».)

Если вы хотите выяснить, может ли пользователь получить доступ к произвольному пути, который определяется реализацией hook_menu (), вам может потребоваться извлечь запись из базы данных и оценить ее параметр «обратный вызов доступа».

ответил gapple 28 J0000006Europe/Moscow 2011, 00:37:18
2
    $node = node_load(123);

    $account = user_load(456);

    if (node_access("update", $node, $account) === TRUE) 
   {

         print "access";    
    }
ответил Mahipal Purohit 19 22013vEurope/Moscow11bEurope/MoscowTue, 19 Nov 2013 16:38:22 +0400 2013, 16:38:22

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132