Controlla se l'utente ha accesso a una determinata pagina


23

Come posso determinare se un utente è autorizzato ad accedere a una determinata pagina?


Non hai specificato quale versione di Drupal usi. Maggiori dettagli sul tuo obiettivo sarebbero anche utili; nei casi più comuni Drupal gestirà automaticamente l'accesso al menu.
Dylan Tack,

Risposte:


25

Se si desidera verificare se l'utente attualmente connesso ha accesso a una pagina, è possibile utilizzare il seguente codice:

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

$path è il percorso della pagina che si desidera controllare (ad es. nodo / 1, admin / utente / utente).

Il codice funziona in Drupal 6 e versioni successive ed è quello utilizzato da menu_execute_active_handler () .

Il motivo per cui non sto suggerendo di chiamare direttamente il callback di accesso è perché gli argomenti che devono essere passati a quella funzione.

Il codice utilizzato da _menu_check_access () è il seguente (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);
}

Il codice, che deve essere il più generico possibile, non gestisce direttamente un oggetto utente. Ciò significa che non è possibile sostituire l'oggetto utente per l'utente attualmente connesso con un altro oggetto utente.
Il codice deve essere abbastanza generico da gestire definizioni di menu come quelle seguenti:

$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 entrambe le definizioni, gli argomenti di accesso non includono un oggetto utente e in questo caso node_access () utilizza l'oggetto utente per l'utente attualmente connesso. Nel secondo caso uno degli argomenti è l'oggetto nodo ottenuto dall'URL; ad esempio, se l'URL è example.com/node/1, il secondo argomento passato al callback di accesso è l'oggetto nodo per il nodo con ID nodo uguale a 1.
Scrivere un codice che gestisca anche questi casi significherebbe duplicare il codice già esistente in Drupal. Anche se hai duplicato quel codice, ci sarebbe ancora il problema dei callback di accesso che stanno verificando l'accesso rispetto all'utente attualmente connesso.

Se si desidera verificare se un utente che non è l'utente attualmente connesso può accedere a un menu, è innanzitutto necessario modificare il valore della variabile globale $user, utilizzare il codice che ho segnalato all'inizio della mia risposta, quindi ripristinare il valore di $user. Per informazioni su come modificare il valore del globale $user, è possibile visualizzare la rappresentazione a livello di codice di un altro utente senza causare la disconnessione dell'utente attualmente connesso . La differenza è che, invece di utilizzare il valore restituito da drupal_anonymous_user () , si utilizza il valore restituito da user_load () .


Posso sapere in quale hook deve essere scritto questo codice.
Gladiatore,

14

Prova drupal_valid_path () .

La funzione restituisce TRUEè il percorso passato quando esiste un argomento e l'utente corrente ha accesso ad esso. Quindi, se stai lavorando su Drupal 7 e devi controllare l'accesso dell'utente attualmente connesso, è il modo più semplice per procedere:

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

1
In D7, drupal_valid_pathfa perfettamente il lavoro ed è fatto per soddisfare questa esigenza esatta. Utilizza menu_get_item e controlla anche l'accesso.
Weboide

È vero, ma funziona solo per l'utente attualmente connesso. Se vuoi sapere se qualche altro utente può accedere al percorso, drupal_valid_pathnon ti aiuterà.
Andrew Schulman,

@AndrewSchulman Non penso che ci sia un'API per questo, ma puoi cambiare temporaneamente utenti.
Peter

In Drupal 8, questo è stato spostato in \Drupal::service('path.validator')->isValid($path);- vedi la documentazione API
Gogowitsch il

3

Chiamare il valore access callbackspecificato nella voce di menu responsabile della pagina. Quella voce di menu viene solitamente creata da Drupal chiamando l'implementazione di hook_menue viene memorizzata da qualche parte nel database. Attenzione che i dati restituiti da hook_menupotrebbero essere modificati da un'implementazione del modulo hook_menu_alter.

Attenzione che alcuni moduli potrebbero non passare l'utente come argomento separato (come specificato dalla access argumentschiave della voce di menu), ma potrebbero invece utilizzare l' $useroggetto globale . Dovrai verificarlo per ogni modulo che usi.


Questo metodo può essere utilizzato per scoprire se un altro utente diverso dall'agente è autorizzato ad accedere alla pagina.
Oswald,

1
Chiamare il callback di accesso non è facile come chiamare qualsiasi altra funzione, poiché il callback di accesso richiede argomenti specifici; vedere _menu_check_access () , che è la funzione che controlla se l'utente attualmente connesso ha accesso a un menu.
kiamlaluno

2

Dai un'occhiata alla user_access()funzione. Vedi il link per i parametri specificati per ogni versione di Drupal. Dalla pagina della documentazione per Drupal 7-8:

parametri

$ string L'autorizzazione, ad esempio "gestisci nodi", viene controllata.

$ account (facoltativo) L'account da verificare, se non fornito, utilizza l'utente attualmente connesso.

Valore di ritorno

Boolean TRUE se l'utente corrente dispone dell'autorizzazione richiesta.

Tutti i controlli di autorizzazione in Drupal dovrebbero passare attraverso questa funzione. In questo modo, garantiamo un comportamento coerente e assicuriamo che il superutente possa eseguire tutte le azioni.


user_access () serve per verificare se l'utente ha un certo "tipo" di autorizzazioni. Ciò che è necessario è se l'utente può accedere a un determinato "percorso"; ad esempio, se l'utente può accedere a 'nodo / 12'?
Farzan,

Bene, come stai determinando quando un utente ha l'autorizzazione o no? Suppongo che ci sia un'opzione nella pagina dei permessi che hai controllato o non dare a determinati ruoli l'autorizzazione
Laxman13

user_access()non è sempre il callback di accesso utilizzato da un menu; anche così sarebbe, dovresti conoscere gli argomenti di accesso a cui devi passare user_access().
kiamlaluno

So che non è sempre user_access(), ho solo pensato che l'OP avesse in mente un'autorizzazione per verificare se l'utente dovesse avere accesso. Non è una domanda molto descrittiva
Laxman13

Anche se user_access non può controllare l'accesso a un percorso specifico, penso che usare user_access ogni volta che sia possibile sia il modo migliore per controllare l'accesso. Buona risposta @ Laxman13 +1.
AyeshK,

2

Se è necessario sapere se un utente può accedere a un determinato nodo e sta utilizzando un modulo di accesso al nodo, è possibile utilizzare node_access () . (senza un modulo di accesso al nodo hanno solo bisogno dell'autorizzazione 'access content').

Se si desidera capire se un utente può accedere a un percorso arbitrario definito da un'implementazione hook_menu (), potrebbe essere necessario recuperare la voce di menu dal database e valutare il parametro 'access callback'.


2
    $node = node_load(123);

    $account = user_load(456);

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

         print "access";    
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.