Sprawdź, czy użytkownik ma dostęp do określonej strony


23

Jak mogę ustalić, czy użytkownik ma uprawnienia dostępu do określonej strony?


Nie określiłeś, której wersji Drupala używasz. Przydałyby się również więcej szczegółów na temat twojego celu; w najczęstszych przypadkach Drupal automatycznie zajmie się dostępem do menu.
Dylan Tack

Odpowiedzi:


25

Jeśli chcesz sprawdzić, czy aktualnie zalogowany użytkownik ma dostęp do strony, możesz użyć następującego kodu:

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

$path to ścieżka do strony, którą chcesz sprawdzić (np. node / 1, admin / user / user).

Kod działa w wersji Drupal 6 i wyższych, i jest to ten używany z menu_execute_active_handler () .

Powodem, dla którego nie sugeruję bezpośredniego wywoływania wywołania zwrotnego dostępu, jest to, że argumenty należy przekazać do tej funkcji.

Kod używany przez _menu_check_access () jest następujący (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);
}

Kod, który musi być jak najbardziej ogólny, nie obsługuje bezpośrednio obiektu użytkownika. Oznacza to, że nie można zastąpić obiektu użytkownika dla aktualnie zalogowanego użytkownika innym obiektem użytkownika.
Kod musi być na tyle ogólny, aby obsługiwał definicje menu, takie jak następujące:

$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),
);

W obu definicjach argumenty dostępu nie obejmują obiektu użytkownika, a node_access () w tym przypadku używa obiektu użytkownika dla aktualnie zalogowanego użytkownika. W drugim przypadku jednym z argumentów jest obiekt węzła uzyskany z adresu URL; na przykład, jeśli adres URL to example.com/node/1, to drugim argumentem przekazanym do wywołania zwrotnego dostępu jest obiekt węzła dla węzła o identyfikatorze węzła równym 1.
Pisanie kodu obsługującego te przypadki oznaczałoby także duplikowanie kodu już istnieje w Drupal. Nawet jeśli zduplikowałeś ten kod, nadal występowałby problem wywołań zwrotnych dostępu, które sprawdzają dostęp w stosunku do aktualnie zalogowanego użytkownika.

Jeśli chcesz sprawdzić, czy użytkownik, który nie jest aktualnie zalogowanym użytkownikiem, może uzyskać dostęp do menu, najpierw zmień wartość zmiennej globalnej $user, użyj kodu podanego na początku mojej odpowiedzi, a następnie przywróć wartość $user. Aby zmienić wartość globalną $user, możesz zobaczyć Programistyczne podszywanie się pod innego użytkownika bez powodowania wylogowania aktualnie zalogowanego użytkownika . Różnica polega na tym, że zamiast używać wartości zwracanej przez drupal_anonymous_user () , używasz wartości zwróconej przez user_load () .


Czy mogę wiedzieć, w którym haku należy napisać ten kod.
Gladiator

14

Spróbuj drupal_valid_path () .

Zwracana funkcja TRUEto ścieżka przekazywana, ponieważ istnieje argument, a bieżący użytkownik ma do niego dostęp. Tak więc, jeśli pracujesz nad Drupalem 7 i musisz sprawdzić dostęp do aktualnie zalogowanego użytkownika, jest to najłatwiejszy sposób:

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

1
W D7 drupal_valid_pathwykonuje to zadanie idealnie i został stworzony, aby spełnić dokładnie tę potrzebę. Używa menu_get_item i sprawdza również dostęp.
Weboide,

To prawda, ale działa tylko dla aktualnie zalogowanego użytkownika. Jeśli chcesz wiedzieć, czy jakiś inny użytkownik może uzyskać dostęp do ścieżki, drupal_valid_pathnie pomoże.
Andrew Schulman,

@AndrewSchulman Nie sądzę, że istnieje interfejs API do tego, ale możesz tymczasowo przełączać użytkowników.
peterpoe

W Drupal 8 przeniesiono to do \Drupal::service('path.validator')->isValid($path);- patrz dokumentacja API
Gogowitsch

3

Zadzwoń pod numer access callbackokreślony w pozycji menu odpowiedzialnej za stronę. Ta pozycja menu jest zwykle tworzona przez Drupala wywołującego implementację hook_menui jest przechowywana gdzieś w bazie danych. Uwaga: zwracane dane hook_menumogą zostać zmienione przez moduł implementujący hook_menu_alter.

Uważaj, że niektóre moduły mogą nie przekazywać użytkownika jako osobnego argumentu (zgodnie z access argumentskluczem pozycji menu), ale zamiast tego mogą używać $userobiektu globalnego . Będziesz musiał to sprawdzić dla każdego używanego modułu.


Tej metody można użyć, aby dowiedzieć się, czy jakiś inny użytkownik niż użytkownik działający może uzyskać dostęp do strony.
Oswald

1
Wywołanie wywołania zwrotnego dostępu nie jest tak łatwe jak wywołanie jakiejkolwiek innej funkcji, ponieważ wywołanie zwrotne dostępu wymaga konkretnych argumentów; zobacz _menu_check_access () , która jest funkcją sprawdzającą, czy aktualnie zalogowany użytkownik ma dostęp do menu.
kiamlaluno

2

Sprawdź user_access()funkcję. Zobacz link do określonych parametrów dla każdej wersji Drupala. Ze strony dokumentacji dla Drupala 7-8:

Parametry

$ string Sprawdzane jest uprawnienie, takie jak „administruj węzłami”.

$ konto (opcjonalnie) Konto do sprawdzenia, jeśli nie podano, aktualnie zalogowany użytkownik.

Zwracana wartość

Wartość logiczna PRAWDA, jeśli bieżący użytkownik ma wymagane uprawnienie.

Wszystkie kontrole uprawnień w Drupal powinny przejść tę funkcję. W ten sposób gwarantujemy spójne zachowanie i zapewniamy, że administrator może wykonywać wszystkie działania.


user_access () służy do sprawdzania, czy użytkownik ma określony „typ” uprawnień. Konieczne jest, aby użytkownik mógł uzyskać dostęp do określonej „ścieżki”; na przykład, czy użytkownik może uzyskać dostęp do „node / 12”?
farzan

Jak zatem określasz, kiedy użytkownik ma pozwolenie, czy nie? Zakładam, że na stronie uprawnień jest opcja, którą albo sprawdziłeś, albo nie udzieliłeś pewnej roli uprawnieniu
Laxman13,

user_access()nie zawsze jest wywołaniem zwrotnym dostępu używanym przez menu; nawet gdyby tak było, powinieneś znać argumenty dostępu, które musisz przekazać user_access().
kiamlaluno

Wiem, że nie zawsze user_access(), tylko pomyślałem, że OP miał na myśli pozwolenie, aby sprawdzić, czy użytkownik powinien mieć dostęp. Niezbyt opisowe pytanie
Laxman13

Mimo że user_access nie może sprawdzić dostępu do określonej ścieżki, myślę, że użycie user_access, gdy tylko jest to możliwe, jest najlepszym sposobem na sprawdzenie dostępu. Dobra odpowiedź @ Laxman13 +1.
AyeshK,

2

Jeśli chcesz wiedzieć, czy użytkownik może uzyskać dostęp do określonego węzła i używa modułu dostępu do węzła, możesz użyć node_access () . (bez modułu dostępu do węzła potrzebują jedynie uprawnienia do „dostępu do treści”).

Jeśli chcesz dowiedzieć się, czy użytkownik może uzyskać dostęp do dowolnej ścieżki zdefiniowanej przez implementację hook_menu (), być może będziesz musiał pobrać pozycję menu z bazy danych i ocenić jej parametr „wywołania zwrotnego dostępu”.


2
    $node = node_load(123);

    $account = user_load(456);

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

         print "access";    
    }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.