Come posso accedere a livello di codice a un utente?


41

Sto cercando l'API che mi permetterà di accedere a un utente passandogli nome utente e password. Qualcuno ha esperienza con questo?

Per chiarire, sto provando a creare una casella di accesso AJAX che appare come popup nella home page e non aggiorno la pagina in caso di credenziali errate, ma solo se l'accesso è corretto. Quindi ecco cosa ho fatto finora:

Aggiornare

Ora carico il modulo di accesso sulla mia homepage, quindi alla presentazione lancio una richiesta AJAX che invia le credenziali a questo script:

function user_login_submit_try() {
  global $user;  

  $uid = user_authenticate($_POST['name'],$_POST['pass']);    
  $arr = array ('name'=>$_POST['name'],'pass'=>$_POST['pass']);
  if ($uid){
    $user = user_load($uid);
    user_login_finalize($arr);
  }

  echo drupal_json_encode($uid); 
  exit;
}; 

Finora funziona, ma le mie preoccupazioni sono (come menzionato da googletorp) problemi di sicurezza; sembra che nessuna delle API che ho usato in questo script abbia disinfettato i dati in ogni caso.

Qualcuno vedrebbe un modo migliore per farlo?


Per quale motivo dovresti accedere a un utente dal codice usando username e password?
kiamlaluno

@ kiamlaluno Perché ho bisogno di usare Ajax nel modulo di login. Nelle mie precedenti domande: drupal.stackexchange.com/questions/5780/… drupal.stackexchange.com/questions/5781/… Non sono riuscito a risolvere nessuno di questi due problemi, quindi ho optato per una richiesta Ajax personalizzata.
silkAdmin,

Risposte:


33

Questo potrebbe aiutare qualcuno:

function mymodule_user_login_credentials($username, $password)
{
    if(user_authenticate($username, $password))
    {
      $user_obj = user_load_by_name($username);
      $form_state = array();
      $form_state['uid'] = $user_obj->uid;      
      user_login_submit(array(), $form_state);
      return true;
    }
    else
    {
        return false;
    }
}

Una versione migliore basata sul commento:

function mymodule_user_login_credentials($username, $password)
{
    if($uid = user_authenticate($username, $password))
    {
      user_login_submit(array(), array('uid' => $uid));
      return true;
    }
    else
    {
        return false;
    }
}

3
user_authenticate restituisce già $ uid, quindi non è necessario caricare l'oggetto utente;)
FLY

7
Il secondo blocco di codice non funzionerà; Il secondo arg di user_login_submit è passato da ref; passandolo l'output di array () fallirà.
Shawn Conn,

Come verrebbe utilizzata questa risposta per accedere automaticamente a un utente dopo che sono stati creati utilizzando un modulo di registrazione? Vorrei farlo, ma la password è un hash quando fornita tramite l'oggetto account come parametro, hook_user_insertma le funzioni sopra nella risposta vogliono la password come testo normale originale. Immagino che dovrò provare hook_form_alterinvece ...
therobyouknow il

Per le persone in cerca di accesso automatico direttamente dopo la creazione del nuovo utente (ad es. Tramite un modulo di registrazione per la registrazione dell'utente, ad esempio "utente / registro"), consultare questa soluzione: drupal.stackexchange.com/a/254905/1082
therobyouknow

19

Non esiste una semplice funzione API per questo.

Puoi fare ciò che Drupal fa:

  1. Prova la password eseguendo una query sul database, vedi:

user_login_name_validate ()
user_login_authenticate_validate ()
user_login_final_validate ()

  1. Sovrascrivi il global $user.

    global $user;
    $user = user_load($uid);
    
  2. Gestire le sessioni

user_login_finalize($form_state);

Per i passaggi 2 e 3 vedere user_login_submit()

Tutte queste funzioni si basano sul richiamo da un modulo. Il flusso normale è che i gestori di validazione testano l'input dell'utente e restituiscono l'UID dell'utente se la validazione passa. Il gestore di invio gestisce quindi l'effettivo accesso dell'utente e il hook utente chiamante.


grazie googletorp, lo proverò, anche se questo mi fa chiedere come funzionano insieme queste funzioni. Come si fa a sapere che ho invocato il precedente?
silkAdmin,

oh e se non ho la variabile From_state disponibile ma solo nome utente e password, posso ricostruirla in questo modo: $form_state['value']['name'] = $_POST['name']e così via ..
silkAdmin

@silk Dovresti sempre usare Drupal FAPI che ti dà la $form_statevariabile. Ci sono molti bei controlli di sicurezza che altrimenti perderesti e che potresti aprire il tuo sito per attacchi. Quando si tratta di accedere a un utente, non si vuole perdere quella sicurezza.
googletorp

Controlla la mia domanda aggiornata, mi piacerebbe davvero sapere se i miei input vengono ripuliti. Grazie
silkAdmin,

Ci dispiace, sembra che la modifica non abbia funzionato la prima volta, ora è aggiornata.
silkAdmin,

7

Se è necessario ottenere l'oggetto utente per l'account utente per il quale si conoscono nome utente e password, è possibile utilizzare il seguente codice:

function mymodule_get_user(name, $password) {
  $account = FALSE;

  if ($uid = user_authenticate($name, $password)) {
    $account = user_load($uid);
  }

  return $account;
}

$accountlo sarà FALSEse l'oggetto utente non può essere trovato o caricato.

Dovresti usare questo codice quando, ad esempio, il tuo modulo ottiene il nome utente e la password come input da un utente, verifica se sono corretti e quindi fa qualcosa con l'oggetto utente.
Se stai scrivendo un modulo che deve impersonare un utente per scrivere un commento o stai facendo qualcos'altro che deve risultare come fatto da un utente, questo è ciò che fa il modulo di tracciamento dei problemi del Progetto quando si chiude un report di problemi che è stato nel stato fisso per due settimane (in tal caso, aggiunge il commento "Chiuso automaticamente - problema risolto per 2 settimane senza attività" che risulta scritto dall'utente "Messaggio di sistema"), quindi non sono necessari nome utente e password. Devi solo caricare l'oggetto utente per il quale conosci l'ID utente.

Per quanto ne so, non ci sono problemi di sicurezza con il codice che ho segnalato.
Potresti voler limitare il numero di accessi falliti; o per bloccare temporaneamente l'IP che tenta di accedere senza successo o tenta diversi accessi in breve tempo.


grazie Kiamlaluno, è un po 'quello che ho fatto, ma ora mi preoccupo dei problemi di sicurezza, controlla la mia domanda aggiornata
silkAdmin,

3

Questo codice funziona davvero

//login
$uid = user_authenticate($username, $password);
global $user;
$user = user_load($uid);    
//login finalize
watchdog('remote_user', 'Session opened for %name.', array('%name' => $user->name));
$user->login = REQUEST_TIME;
db_update('users')
  ->fields(array('login' => $user->login))
  ->condition('uid', $user->uid)
  ->execute();
drupal_session_regenerate();

Non invoca hook_user_login, vedere la funzione user_login_finalize ().
skorzh,

2

Risposta pulita da quanto sopra. Il controllo di utente e password è una funzione aggiuntiva. Inoltre, il form_state falso deve essere una variabile da passare in riferimento alla funzione o genera un errore.

Quindi abbiamo:

function mymodule_log_in_by_uid($uid) {
    $faux_form_state = array('uid' => $uid);
    user_login_submit(array(), $faux_form_state);
}

0

L'utente riceverà la sessione e accederà anche ad altre pagine:

function custom_log_in_by_uid($uid) {
    $form_state = array('uid' => $uid);
    user_login_submit(array(), $form_state);
}

0

A volte abbiamo bisogno di un accesso rapido dall'URL o dalla password dell'amministratore dimenticata. Basta implementare di seguito due funzioni per accedere come utente 1 in Drupal.

function mymodule_menu(){
    $items['login/as/admin'] = array(
        'title' => 'Login as admin account',
        'page callback' => 'mymodule_login_as_admin',
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );
    return $items;
}
function mymodule_login_as_admin(){
    global $user;
    $user = user_load(1);
    return "Global user set as admin. Please refresh page ";
}
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.