Überprüfen Sie, ob der Benutzer Zugriff auf eine bestimmte Seite hat

23

Wie kann ich feststellen, ob ein Benutzer berechtigt ist, auf eine bestimmte Seite zuzugreifen?

Farzan
quelle
Sie haben nicht angegeben, welche Version von Drupal Sie verwenden. Weitere Details zu Ihrem Ziel wären ebenfalls hilfreich. In den meisten Fällen übernimmt Drupal den Menüzugriff automatisch.
Dylan Tack

Antworten:

25

Wenn Sie überprüfen möchten, ob der aktuell angemeldete Benutzer Zugriff auf eine Seite hat, können Sie den folgenden Code verwenden:

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

$path ist der Pfad der Seite, die Sie überprüfen möchten (z. B. Knoten / 1, Administrator / Benutzer / Benutzer).

Der Code funktioniert in Drupal 6 und höheren Versionen und wird von menu_execute_active_handler () verwendet .

Der Grund, warum ich nicht vorschlage, den Zugriffsrückruf direkt aufzurufen, ist, dass die Argumente an diese Funktion übergeben werden müssen.

Der von _menu_check_access () verwendete Code ist der folgende (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);
}

Der Code, der so allgemein wie möglich sein muss, behandelt ein Benutzerobjekt nicht direkt. Dies bedeutet, dass das Benutzerobjekt für den aktuell angemeldeten Benutzer nicht durch ein anderes Benutzerobjekt ersetzt werden kann.
Der Code muss generisch genug sein, um Menüdefinitionen wie die folgenden verarbeiten zu können:

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

In beiden Definitionen enthalten die Zugriffsargumente kein Benutzerobjekt, und node_access () verwendet in diesem Fall das Benutzerobjekt für den derzeit angemeldeten Benutzer. Im zweiten Fall ist eines der Argumente das Knotenobjekt, das von der URL abgerufen wird. Wenn die URL beispielsweise example.com/node/1 lautet, ist das zweite Argument, das an den Zugriffsrückruf übergeben wird, das Knotenobjekt für den Knoten mit der Knoten-ID 1. Das
Schreiben von Code, der auch diese Fälle behandelt, bedeutet, Code zu duplizieren in Drupal bereits vorhanden. Auch wenn Sie diesen Code dupliziert haben, besteht immer noch das Problem der Zugriffsrückrufe, die den Zugriff auf den aktuell angemeldeten Benutzer überprüfen.

Wenn Sie überprüfen möchten, ob ein Benutzer, der nicht der aktuell angemeldete Benutzer ist, auf ein Menü zugreifen kann, ändern Sie zuerst den Wert der globalen Variablen $user, verwenden Sie den Code, den ich am Anfang meiner Antwort angegeben habe, und stellen Sie dann den Wert von wieder her $user. Informationen zum Ändern des globalen Werts $userfinden Sie unter Programmgesteuerter Identitätswechsel für einen anderen Benutzer, ohne dass sich der aktuell angemeldete Benutzer abmeldet . Der Unterschied besteht darin, dass Sie anstelle des von drupal_anonymous_user () zurückgegebenen Werts den von user_load () zurückgegebenen Wert verwenden .

kiamlaluno
quelle
Darf ich wissen, in welchen Hook dieser Code geschrieben werden soll.
Gladiator
14

Versuchen Sie es mit drupal_valid_path () .

Die Funktion gibt TRUEden Pfad zurück, der als Argument übergeben wurde und auf den der aktuelle Benutzer Zugriff hat. Wenn Sie also an Drupal 7 arbeiten und den Zugriff auf den aktuell angemeldeten Benutzer überprüfen müssen, ist dies der einfachste Weg:

if (drupal_valid_path('my/path')) {
  // Your code here...
}
Peterpoe
quelle
1
In D7 drupal_valid_pathmacht es die Arbeit perfekt und ist dafür gemacht, genau dieses Bedürfnis zu erfüllen. Es verwendet menu_get_item und überprüft auch den Zugriff.
Weboide
Das stimmt, aber es funktioniert nur für den aktuell angemeldeten Benutzer. Wenn Sie wissen möchten, ob ein anderer Benutzer auf den Pfad zugreifen kann, drupal_valid_pathhilft Ihnen das nicht weiter.
Andrew Schulman
@ AndrewSchulman Ich glaube nicht, dass es eine API dafür gibt, aber Sie können vorübergehend die Benutzer wechseln.
Peterpoe
In Drupal 8 wurde dies verschoben \Drupal::service('path.validator')->isValid($path);- siehe API-Dokumentation
Gogowitsch
3

Rufen Sie das auf access callback, das im Menüeintrag angegeben ist, der für die Seite verantwortlich ist. Dieser Menüeintrag wird normalerweise von Drupal erstellt, der die Implementierung von aufruft, hook_menuund ist irgendwo in der Datenbank gespeichert. Beachten Sie, dass die von zurückgegebenen Daten hook_menumöglicherweise von einem implementierenden Modul geändert werden hook_menu_alter.

Beachten Sie, dass einige Module den Benutzer möglicherweise nicht als separates Argument übergeben (wie durch den access argumentsSchlüssel des Menüeintrags angegeben), sondern stattdessen das globale $userObjekt verwenden. Sie müssen dies für jedes verwendete Modul überprüfen.

Oswald
quelle
Diese Methode kann verwendet werden, um herauszufinden, ob ein anderer Benutzer als der handelnde Benutzer auf die Seite zugreifen darf.
Oswald
1
Das Aufrufen des Zugriffsrückrufs ist nicht so einfach wie das Aufrufen einer anderen Funktion, da für den Zugriffsrückruf bestimmte Argumente erforderlich sind. Siehe _menu_check_access () . Mit dieser Funktion wird geprüft , ob der aktuell angemeldete Benutzer Zugriff auf ein Menü hat.
kiamlaluno
2

Überprüfen Sie die user_access()Funktion. Siehe den Link für die angegebenen Parameter für jede Version von Drupal. Auf der Dokumentationsseite für Drupal 7-8:

Parameter

$ string Die Berechtigung, z. B. "Knoten verwalten", auf die geprüft wird.

$ account (optional) Das zu überprüfende Konto, falls nicht angegeben, der aktuell angemeldete Benutzer.

Rückgabewert

Boolean TRUE, wenn der aktuelle Benutzer die angeforderte Berechtigung hat.

Alle Berechtigungsprüfungen in Drupal sollten diese Funktion durchlaufen. Auf diese Weise garantieren wir ein konsistentes Verhalten und stellen sicher, dass der Superuser alle Aktionen ausführen kann.

Laxman13
quelle
user_access () dient zur Überprüfung, ob der Benutzer über einen bestimmten "Typ" von Berechtigungen verfügt. Was erforderlich ist, ist, wenn der Benutzer auf einen bestimmten "Pfad" zugreifen kann; Zum Beispiel, wenn der Benutzer auf 'node / 12' zugreifen kann.
Farzan
Nun, wie stellen Sie fest, wann ein Benutzer die Berechtigung hat oder wann nicht? Ich würde annehmen, dass es eine Option auf der Berechtigungsseite gibt, die Sie entweder
aktiviert
user_access()ist nicht immer der von einem Menü verwendete Zugriffsrückruf; Trotzdem sollten Sie die Zugriffsargumente kennen, an die Sie übergeben müssen user_access().
kiamlaluno
Ich weiß, dass dies nicht immer user_access()der Fall ist. Ich habe nur gedacht, dass das OP eine Berechtigung hat, um zu prüfen, ob der Benutzer Zugriff haben sollte. Keine sehr beschreibende Frage
Laxman13
Auch wenn user_access den Zugriff auf einen bestimmten Pfad nicht überprüfen kann, ist die Verwendung von user_access nach Möglichkeit die beste Methode, um den Zugriff zu überprüfen. Gute Antwort @ Laxman13 +1.
AyeshK
2

Wenn Sie wissen möchten, ob ein Benutzer auf einen bestimmten Knoten zugreifen kann und ein Knotenzugriffsmodul verwendet, können Sie node_access () verwenden . (Ohne ein Knotenzugriffsmodul benötigen sie lediglich die Berechtigung "Zugriff auf Inhalte".)

Wenn Sie herausfinden möchten, ob ein Benutzer auf einen beliebigen Pfad zugreifen kann, der durch eine Implementierung von hook_menu () definiert ist, müssen Sie möglicherweise den Menüeintrag aus der Datenbank abrufen und seinen Parameter 'access callback' auswerten.

schnappen
quelle
2
    $node = node_load(123);

    $account = user_load(456);

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

         print "access";    
    }
Mahipal Purohit
quelle