Wie melde ich mich programmgesteuert bei einem Benutzer an?

41

Ich suche nach der API, mit der ich einen Benutzer anmelden kann, indem ich ihm den Benutzernamen und das Kennwort übergebe. Hat jemand Erfahrung damit?

Zur Verdeutlichung versuche ich, ein AJAX-Anmeldefeld zu erstellen, das als Popup auf der Startseite angezeigt wird, und die Seite bei falschen Anmeldeinformationen nicht zu aktualisieren, sondern nur, wenn die Anmeldung korrekt ist. Also hier ist, was ich bisher gemacht habe:

Aktualisieren

Ich lade jetzt das Anmeldeformular auf meiner Homepage und starte bei der Übermittlung eine AJAX-Anfrage, die einen Berechtigungsnachweis für dieses Skript sendet:

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;
}; 

Bisher funktioniert es, aber meine Sorgen sind (wie von googletorp erwähnt) Sicherheitsprobleme. Es scheint, dass keine der in diesem Skript verwendeten APIs die Daten in irgendeiner Weise bereinigt hat.

Würde jemand einen besseren Weg sehen, dies zu tun?

silkAdmin
quelle
Aus welchem ​​Grund müssten Sie einen Benutzer aus dem Code mit Benutzername und Kennwort anmelden?
kiamlaluno
@ kiamlaluno Weil ich Ajax im Anmeldeformular verwenden muss. In meinen vorangegangenen Fragen: drupal.stackexchange.com/questions/5780/… drupal.stackexchange.com/questions/5781/… Ich konnte keines dieser beiden Probleme lösen und habe mich für eine benutzerdefinierte Ajax-Anfrage entschieden.
SilkAdmin

Antworten:

33

Dies könnte jemandem helfen:

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;
    }
}

Eine bessere Version basierend auf dem Kommentar:

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;
    }
}
user1750
quelle
3
user_authenticate gibt bereits die $ uid zurück, sodass das Benutzerobjekt nicht geladen werden muss;)
FLY
7
Der zweite Codeblock funktioniert nicht. Das 2. Argument von user_login_submit wird mit ref übergeben. Wenn Sie ihn übergeben, schlägt die Ausgabe von array () fehl.
Shawn Conn
Wie würde diese Antwort verwendet, um einen Benutzer automatisch anzumelden, nachdem er mithilfe eines Registrierungsformulars erstellt wurde? Ich würde das gerne tun, aber das Passwort ist ein Hash, wenn es über das Account-Objekt als Parameter in bereitgestellt wird, hook_user_insertaber die obigen Funktionen in der Antwort möchten, dass das Passwort der ursprüngliche Klartext ist. Ich denke, ich muss es hook_form_alterstattdessen versuchen ...
wissen,
Leute, die direkt nach der Erstellung des neuen Benutzers nach einer automatischen Anmeldung suchen (z. B. über ein Anmeldeformular für den Benutzer, z. B. "Benutzer / Registrieren"), sehen sich diese Lösung an: drupal.stackexchange.com/a/254905/1082
therobyouknow
19

Dafür gibt es keine einfache API-Funktion.

Sie können tun, was Drupal tut:

  1. Testen Sie das Passwort, indem Sie die Datenbank abfragen. Siehe:

user_login_name_validate ()
user_login_authenticate_validate ()
user_login_final_validate ()

  1. Überschreiben Sie die global $user.

    global $user;
    $user = user_load($uid);
    
  2. Sitzungen abwickeln

user_login_finalize($form_state);

Für Schritt zwei und 3 siehe user_login_submit()

Alle diese Funktionen basieren auf dem Aufruf aus einem Formular. Der normale Ablauf besteht darin, dass die Validierungs-Handler die Benutzereingaben testen und die UID des Benutzers zurückgeben, wenn die Validierung erfolgreich ist. Der Submit-Handler übernimmt dann die eigentliche Anmeldung des Benutzers und des aufrufenden Benutzer-Hooks.

googletorp
quelle
danke googletorp, ich werde das ausprobieren, obwohl ich mich fragen kann, wie diese Funktionen zusammenarbeiten. Woher weiß man, dass ich den Präzedenzfall aufgerufen habe?
SilkAdmin
Oh, und wenn ich nicht die Variable From_state zur Verfügung habe, sondern nur Benutzername und Passwort, kann ich sie wie folgt neu erstellen: $form_state['value']['name'] = $_POST['name']und so weiter.
silkAdmin
@silk Du solltest immer das Drupal FAPI verwenden, das dir die $form_stateVariable gibt. Es gibt viele nette Sicherheitsüberprüfungen, die Sie sonst verlieren und möglicherweise Ihre Site für Angriffe öffnen würden. Wenn Sie sich bei einem Benutzer anmelden, möchten Sie diese Sicherheit nicht verlieren.
googletorp
Bitte überprüfen Sie meine aktualisierte Frage, ich möchte wirklich wissen, ob meine Eingaben aufgeräumt werden .. Danke
silkAdmin
Es tut uns leid, dass die Bearbeitung beim ersten Mal nicht funktioniert hat, jetzt ist sie aktualisiert.
SilkAdmin
7

Wenn Sie das Benutzerobjekt für das Benutzerkonto abrufen müssen, für das Sie Benutzername und Kennwort kennen, können Sie den folgenden Code verwenden:

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

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

  return $account;
}

$accountWird angezeigt, FALSEwenn das Benutzerobjekt nicht gefunden oder geladen werden kann.

Sie sollten diesen Code verwenden, wenn Ihr Modul beispielsweise den Benutzernamen und das Kennwort als Eingabe von einem Benutzer erhält, überprüft, ob sie korrekt sind, und dann etwas mit dem Benutzerobjekt unternimmt.
Wenn Sie ein Modul schreiben, das die Identität eines Benutzers annehmen muss, um einen Kommentar zu verfassen, oder wenn Sie etwas anderes tun müssen, das als Ergebnis von einem Benutzer ausgeführt werden muss, führt das Modul Projekt-Fehlerverfolgung genau dies aus, wenn Sie einen Fehlerbericht schließen, der sich im befunden hat fester Status für zwei Wochen (in diesem Fall wird der Kommentar "Automatisch geschlossen - Problem für 2 Wochen ohne Aktivität behoben" hinzugefügt, der vom Benutzer "Systemmeldung" geschrieben wurde. Sie benötigen dann keinen Benutzernamen und kein Kennwort. Sie laden einfach das Benutzerobjekt, für das Sie die Benutzer-ID kennen.

Soweit ich weiß, gibt es keine Sicherheitsprobleme mit dem von mir gemeldeten Code.
Sie können die Anzahl der fehlgeschlagenen Anmeldungen begrenzen. oder um die IP vorübergehend zu blockieren, die versucht, sich ohne Erfolg anzumelden, oder versucht, sich in kurzer Zeit anders anzumelden.

kiamlaluno
quelle
danke kiamlaluno, es ist so, wie ich es getan habe, aber ich mache mir jetzt Sorgen um Sicherheitsprobleme, bitte
schau dir
3

Dieser Code funktioniert wirklich

//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();
vacho
quelle
Hook_user_login wird nicht aufgerufen (siehe user_login_finalize () - Funktion).
Skorzh
2

Aufgeräumte Antwort von oben. Die Überprüfung von Benutzer und Passwort ist eine zusätzliche Funktion. Außerdem muss der gefälschte form_state eine Variable sein, die als Referenz an die Funktion übergeben werden soll, oder es wird ein Fehler ausgegeben.

Daher haben wir:

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

Der Benutzer erhält die Sitzung und wird auch auf anderen Seiten angemeldet:

function custom_log_in_by_uid($uid) {
    $form_state = array('uid' => $uid);
    user_login_submit(array(), $form_state);
}
Віктор Плясун
quelle
0

Manchmal müssen wir uns schnell über die URL anmelden oder das Administrator-Passwort vergessen. Implementieren Sie einfach die folgenden zwei Funktionen, um sich als Benutzer 1 in Drupal anzumelden.

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 ";
}
Girish Bathyal
quelle