Перевірте, чи має користувач доступ до певної сторінки


23

Як я можу визначити, чи має користувач дозвіл на доступ до певної сторінки?


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

Відповіді:


25

Якщо ви хочете перевірити, чи має користувач, який зараз увійшов, має доступ до сторінки, ви можете використовувати такий код:

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


Можу чи я дізнатися , в якій гачок цей код повинен бути написаний.
Гладіатор

14

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

Функція повертається TRUE- це шлях, пройдений у міру існування аргументу, і поточний користувач має доступ до нього. Отже, якщо ви працюєте над Drupal 7 і вам потрібно перевірити доступ на поточно зареєстрованого користувача, це найпростіший шлях:

if (drupal_valid_path('my/path')) {
  // Your code here...
}

1
У D7 drupal_valid_pathвиконує цю роботу ідеально і робиться для задоволення цієї точної потреби. Він використовує menu_get_item і перевіряє доступ.
Weboide

Це правда, але вона працює лише для користувача, який зараз увійшов. Якщо ви хочете знати, чи може інший користувач отримати доступ до шляху, вам drupal_valid_pathце не допоможе.
Ендрю Шульман

@AndrewSchulman Я не думаю, що для цього є API, але ви можете тимчасово перемикати користувачів.
peterpoe

В Drupal 8, це переїхав \Drupal::service('path.validator')->isValid($path);- дивіться документацію по API
Gogowitsch

3

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

Пам'ятайте , що деякі модулі можуть не пройти користувачеві як окремий аргумент (як зазначено в access argumentsключі пункту меню), але замість цього може використовувати глобальний $userоб'єкт замість. Ви повинні перевірити це для кожного модуля , який ви використовуєте.


Цей метод може бути використаний для з'ясування того, чи якийсь інший користувач, крім діючого користувача, має право доступу до сторінки.
Освальд

1
Виклик на зворотний дзвінок доступу не так просто , як виклик будь-який інший функції, а функція зворотного виклику доступ вимагає конкретних аргументів; див. _menu_check_access () , яка є функцією, яка перевіряє, чи має поточний користувач доступ до меню.
kiamlaluno

2

Перевірте user_access()функцію. Дивіться посилання на вказані параметри для кожної версії Drupal.

Параметри

$ string Дозвіл, наприклад "адміністративні вузли", перевіряється на.

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

Повернене значення

Логічне значення TRUE, якщо поточний користувач має необхідний дозвіл.

Таким чином, ми гарантуємо послідовну поведінку та гарантуємо, що супервайзер може виконувати всі дії.


наприклад, якщо користувач може отримати доступ до "node / 12"?
фарзан

Я б припустити , що це варіант на сторінці дозволів , що ви або зареєстровані або не давати певним ролям дозволу
Laxman13

user_access()не завжди є зворотний дзвінок доступу, який використовується меню; навіть якщо це було б, ви повинні знати аргументи доступу, які вам потрібно передати user_access().
kiamlaluno

Я знаю , що це не завжди user_access(), просто зрозумів , що ОП мав дозвіл на увазі , щоб перевірити , щоб побачити , якщо користувач повинен мати доступ. Не дуже описове запитання
Laxman13

Незважаючи на те, user_access не може перевірити доступ до певного шляху, я думаю , з допомогою user_access коли це можливо , найкращий спосіб , щоб перевірити доступ. Хороший відповідь @ Laxman13 +1.
АйешК

2

(без модуля доступу до вузла їм просто потрібен дозвіл "доступу до вмісту".)

Якщо ви хочете з’ясувати, чи може користувач отримати доступ до довільного шляху, який визначається реалізацією mock_menu (), можливо, вам доведеться вийти з меню бази даних та оцінити її параметр «зворотний виклик доступу».


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.