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


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

 23
Author: Free Radical, 2011-06-27

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().

 25
Author: kiamlaluno, 2017-04-13 12:47:09

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

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

if (drupal_valid_path('my/path')) {
  // Your code here...
}
 14
Author: peterpoe, 2013-01-12 15:09:59

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

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

 3
Author: Oswald, 2011-06-27 19:40:52

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

Параметры

$строка разрешения, такого как "администрирование узлов", на наличие которого проверяется.

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

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

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

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

 2
Author: Laxman13, 2011-06-27 14:49:55

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

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

 2
Author: gapple, 2011-06-27 20:37:18
    $node = node_load(123);

    $account = user_load(456);

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

         print "access";    
    }
 2
Author: Mahipal Purohit, 2014-02-17 09:11:20