Nach Benutzeranmeldung umleiten

13

Ich möchte Benutzer nach dem Anmelden umleiten. Kann hook_user_login()ich die Umleitung über ausführen? Wie füge ich den Parameter für die Umleitung hinzu?

John Chan
quelle

Antworten:

19

Sie müssen das Anmeldeformular ändern und einen Submit-Handler hinzufügen, der sich um die Umleitung kümmert. Sie können nicht $form_state->setRedirectUrl()direkt im Formular ändern, da es von überschrieben wird UserForm::submitForm().

/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_user_login_form_alter(&$form, FormStateInterface $form_state) {
  $form['#submit'][] = 'mymodule_user_login_submit';
}

/**
 * Form submission handler for user_login_form().
 *
 * Redirects the user to the dashboard after logging in.
 */
function mymodule_user_login_submit(&$form, FormStateInterface $form_state) {
  $url = Url::fromRoute('mymodule.dashboard');

  // Check if a destination was set, probably on an exception controller.
  // @see \Drupal\user\Form\UserLoginForm::submitForm()
  $request = \Drupal::service('request_stack')->getCurrentRequest();
  if (!$request->request->has('destination')) {
    $form_state->setRedirectUrl($url);
  }
  else {
    $request->query->set('destination', $request->request->get('destination'));
  }
}
pfrenssen
quelle
4
Wie von @kiamlaluno beschrieben, kann man auch verwenden$form_state->setRedirect('mymodule.dashboard);
Filipe Miguel Fonseca
3
Bitte erläutern Sie Benutzern, die dieser Antwort folgen, was mymodule.dashboard tun sollte / würde. Wie man das in <front> ändert, nur als Beispiel. Da das Benutzer-Dashboard nach der Anmeldung die Standardumleitung ist, ist dieses Beispiel hier nutzlos. Der neue Benutzer weiß nicht, welche Teile zu ändern sind und wie er sie weiterleiten soll.
Nilsun
1
Um zur Startseite umzuleiten, können Sie das obige Beispiel verwenden, aber die Zeile, die das $ url-Objekt generiert, in $ url = Url :: fromUri ('internal: /') ändern.
OKNATE
1
Ich verstehe nicht, was elsehier los ist? Bestehende Weiterleitung beibehalten?
user1359
1
Sie müssen Drupal \ Core \ Url verwenden; damit es richtig funktioniert
Jignesh Rawal
15

Das Umleiten von Benutzern nach der Anmeldung auf einer Drupal 8-Site unterscheidet sich nicht von der Vorgehensweise auf Drupal 7, mit der Ausnahme, dass der Code für Drupal 8 angepasst werden muss.

Im Speziellen:

  • hook_user_login()wird nicht verwendet, um Benutzer nach der Anmeldung umzuleiten, nur weil das Umleiten von Benutzern in diesem Hook das Aufrufen anderer hook_user_login()Implementierungen verhindern würde .
  • Die richtige Möglichkeit, Benutzer umzuleiten, besteht darin, dem Anmeldeformular einen Formularübermittlungs-Handler hinzuzufügen, der Code ähnlich dem folgenden verwendet.

    $form_state->setRedirect('user.page');

    Beachten Sie, dass user.page der Routing-Name für den Drupal-Pfad ist, unter dem der Benutzer umgeleitet werden soll.
    Wenn Sie eine Instanz der Drupal\Core\UrlKlasse haben, können Sie auch den folgenden Code verwenden.

    $form_state->setRedirectUrl($url);

    Beachten Sie, dass die erste Methode vorzuziehen ist, wenn Sie Benutzer auf eine Seite auf derselben Site umleiten, auf der sie sich angemeldet haben. Die zweite Methode wird normalerweise verwendet, um Benutzer mithilfe einer externen URL umzuleiten.

kiamlaluno
quelle
11

Sie können hook_user_login verwenden und versuchen, zu umzuleitenyourpath

function yourmodule_user_login($account) {
  // We want to redirect user on login.
  $response = new RedirectResponse("yourpath");
  $response->send();
  return;
}

Sie können auch das Rules-Modul verwenden , es gibt jedoch noch KEINE stabile Version für Drupal 8.

Yusef
quelle
Eine gute elegante Lösung, die für mich in Drupal 8.1 funktioniert hat.
Alexei Rayu
3
Ich habe unter ERR_RESPONSE_HEADERS_MULTIPLE_LOCATIONbestimmten Umständen Fehler mit den obigen Anweisungen erhalten. Ich empfehle, sie return;durch exit;zu ersetzen , um sicherzustellen, dass die Umleitung, bei der die Header festgelegt werden, als letztes ausgeführt wird.
2
hook_user_login () wird vor den Submit-Handlern aufgerufen, damit diese nicht aufgerufen werden können. Yogeshs Antwort unten ist ein besserer Weg, dies zu tun.
imclean
9

Etwas zu spät zur Party, aber gemäß https://www.drupal.org/node/2068293#comment-11712455 können Sie das Ziel in hook_user_login () so einstellen, dass es am Ende der Anmeldeverarbeitung umgeleitet wird.

dh

/**
 * Implements hook_user_login().
 */
function mymodule_user_login(\Drupal\user\UserInterface $account) {
  // Ignore password reset.
  $route_name = \Drupal::routeMatch()->getRouteName();
  if ($route_name !== 'user.reset.login') {
    // Do not interfere if a destination was already set.
    $current_request = \Drupal::service('request_stack')->getCurrentRequest();
    if (!$current_request->query->get('destination')) {
      // Default login destination to the dashboard.
      $current_request->query->set(
        'destination',
        \Drupal\Core\Url::fromRoute('mymodule.dashboard')->toString()
      );
    }
  }
}

Die Verwendung von FormState :: setRedirect () gemäß den anderen Antworten deckt wahrscheinlich die Anwendungsfälle der meisten Personen ab und ist möglicherweise die 'richtige' Antwort. Die Verwendung des Zielabfrageparameters mit hook_user_login bedeutet jedoch, dass jedes Formular, das sich beim Benutzer anmeldet, weiterleitet ohne Einmischung oder vorherige Kenntnis eines anderen Teils des Formulars / der Anfrage.

Das heißt, es funktioniert weiterhin mit einem benutzerdefinierten Anmeldeformular und die Verwendung von destination stoppt keine anderen Hooks (die Implementierung erfolgt \Drupal\Core\EventSubscriber\RedirectResponseSubscriberam Ende der Antwortverarbeitung).

* Jede Formularübertragung, die hook_user_login (user_login_finalize ()) aufruft und FormState :: setResponse () nicht manuell aufruft .

Sut3kh
quelle
1
Dies hat den Vorteil, dass die Authentifizierung nicht über ein Anmeldeformular erfolgt. Beeinträchtigt dies jedoch andere Implementierungen von hook_user_login aus anderen Modulen?
Jonathan
1
@Jonathan Nein, es legt nur das Ziel fest und führt keine vorzeitige Anfrage-> send () oder irgendetwas anderes aus (z. B. d7 drupal_goto). Alle anderen Hooks, Rückrufe usw. können wie gewohnt ausgeführt werden, bevor die Aktion ausgeführt wird . So funktioniert das mit der Standard-Drupal-Anmeldeumleitung .
Sut3kh
1
Bitte erläutern Sie Benutzern, die dieser Antwort folgen, was mymodule.dashboard tun sollte / würde. Wie man das in <front> ändert, nur als Beispiel. Da das Benutzer-Dashboard nach der Anmeldung die Standardumleitung ist, ist dieses Beispiel hier nutzlos. Der neue Benutzer weiß nicht, welche Teile zu ändern sind und wie er sie weiterleiten soll.
Nilsun
3
@nilsun mymodule.dashboardist der Routenname und kann durch einen beliebigen Routennamen (dh \Drupal\Core\Url::fromRoute('<front>')->toString()oder \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 123])->toString()) ersetzt werden. Weitere Informationen finden Sie unter drupal.org/docs/8/api/routing-system/routing-system-overview und api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/…
Sut3kh
2
Dadurch wird das Zurücksetzen des Passworts unterbrochen, sodass ich die Antwort herabstimme. (Erstellen eines Formularübermittlungshandlers für user_login_form, wie in einer anderen Antwort vorgeschlagen, funktioniert.)
Hansfn
7

Sie können dies einfach mithilfe von Regeln tun

Reagiere auf: Nachdem sich der Benutzer eingeloggt hat

  • Aktion hinzufügen: Umleiten >> Verwenden Sie dann einen Parameter oder geben Sie Ihre URL ein.
Shrikant Nakade
quelle
3
Die wichtigste Einschränkung ist, dass Rules noch in der Vorabversion von ALPHA für Drupal 8 enthalten ist. Seien Sie also vorsichtig, wenn Sie Stabilität auf Ihrer Website benötigen
Philippe Gilbert,
1
. Die Regeln vermasselt das Login - System , wenn die Website Umleitung nach Benutzer anmeldet auf eine Seite hat in Beware
InspiredCoder
6

Sie können auch das Benutzeranmeldeformular ändern und Ihren eigenen benutzerdefinierten Submit-Handler hinzufügen, um die $ form_state-Umleitung festzulegen, anstatt den Benutzer mit hook_user_login direkt zu Ihrer benutzerdefinierten URL umzuleiten .

<?php
/**
 * Implements hook_form_alter().
 */
function [MODULENAME]_form_alter(&$form, \Drupal\Core\Form\FormStateInterface\FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    // Alter login form and add own custom submit handler.
    case 'user_login_form':
      $form['#submit'][] = '_[MODULENAME]_user_login_form_submit';
      break;
  }
}

/**
 * Custom submit handler for login form.
 */
function _[MODULENAME]_user_login_form_submit($form, FormStateInterface $form_state) {
  // Set redirect to login form.
  $form_state->setRedirect('YOUR.MENU-ROUTER.NAME');
}

Durch Hinzufügen in $ form_state redirect wird sichergestellt, dass die anderen Submit-Handler / Login-Hooks aufgerufen werden.

Wie bei Drupal7 können wir $ form_state ['redirect'] nicht direkt setzen, da $ form_state jetzt ein Klassenobjekt ist. Kasse Formstate :: setRedirect () für weitere Details.

Yogesh
quelle
6

In D8 können Sie zu diesem Zweck das Standard-Seitenmodul des Benutzers verwenden.

Mit diesem Modul können Sie das Ziel anpassen, zu dem ein Benutzer nach dem Anmelden oder Abmelden umgeleitet wird. Sie können nach Rollen oder einzelnen Benutzern anpassen.

Pallavi Chaudhury
quelle
1
Funktioniert, berücksichtigt aber keine Links zum Zurücksetzen des Passworts. Wenn der Benutzer den einmaligen Link zum Festlegen seines Passworts verwendet, leitet er sie zu der in diesem Modul festgelegten Seite und nicht zum Benutzerkonto weiter.
Sorin
1
Dieses Modul bricht das Zurücksetzen des Passworts immer noch ab, daher stimme ich die Antwort herunter. Siehe drupal.org/project/user_default_page/issues/2991916 (Erstellen eines Formularübermittlungshandlers für user_login_form, wie in einer anderen Antwort vorgeschlagen.)
hansfn
4

Dazu gibt es ein einfaches Modul, das mit Drupal 8 kompatibel ist. Es heißt User Default Page .

Mit dem Modul können Sie das Ziel anpassen, zu dem ein Benutzer nach dem Anmelden oder Abmelden umgeleitet wird. Sie können nach Rollen oder einzelnen Benutzern anpassen. Und passen Sie konfigurierbare Drupal-Nachrichten für diese Aktionen an.

Pallavi Chaudhury
quelle
3

hook_user_login() Die Umleitung funktioniert nicht. Sie wird verwendet, wenn Sie beim Anmelden etwas mit dem Benutzer tun möchten. Fx core empfiehlt Benutzern, die lokale Zeitzone festzulegen, wenn sie nicht festgelegt ist.

Stattdessen müssen Sie hook_form_alteralle Anmeldeformulare verwenden und einen benutzerdefinierten Submit-Handler hinzufügen, der die Umleitung für das Formularstatusobjekt festlegt.

googletorp
quelle
2

Ich zeige das Anmeldeformular in meinem eigenen Controller an. Auf diese Weise ist es möglich, das Formular zu manipulieren (und den Benutzer nach der Anmeldung umzuleiten), ohne die Nicht-OO-Hooks:

$fb = $this->formBuilder();
$rc['top'] = ['#markup' => '<p>Willkommen im Kundenbereich von proreos. 
    Bitte melden Sie sich hier mit Ihrem
    Benutzernamen oder Ihrer Email Addresse an.</p>'];
$form = $fb->getForm("Drupal\user\Form\UserLoginForm");

$ug = $this->getUrlGenerator();
$redir = $ug->generateFromRoute('proreos.home', [], 
         ['query' => $this->getDestinationArray(), 'external' => FALSE]);
$form['#action'] = $redir;

$rc['login'] = $form;

return $rc;

Ändern Sie die Route "proreos.home" zu einem beliebigen Ziel.

Grüße

Rainer

Rainer Feike
quelle
1

Sie können das Logintoboggan- Modul zur Umleitung verwenden. Es hat andere Konfigurationen, die nützlich sein können, wenn Sie andere Funktionen wie die Anmeldung mit Benutzernamen wünschen.

Nitvirus
quelle
2
Gute Antwort für D7, aber diese Frage ist mit D8 markiert, und es gibt noch keine Drupal 8-Version von Logintoboggan.
Kelley Curry
1

https://www.drupal.org/project/redirect

  1. Installieren Sie das obige Modul
  2. Fügen Sie der URL einen benutzerdefinierten URL-Pfad als Zielparameter hinzu
  3. Konfigurieren Sie daher das obige Modul, von dem umgeleitet werden soll

    / user / login to / user / login? destination = 'CUSTOM_NODE_PATH'

    • Wollte das Modul r4032login verwenden , um authentifizierten Benutzern den Zugriff auf die betreffende Seite zu ermöglichen, wenn sie die URL kopieren / einfügen oder beispielsweise einen Hyperlink aus Word / Excel verwenden.
    • Andere 'Login Redirect'-Module würden diese Funktionalität überschreiben und es Benutzern nur ermöglichen, auf einer konfigurierten einzelnen Seite zu landen, selbst wenn die Zielparameter in der URL enthalten sind
Abhi
quelle
1

Eine weitere Option speziell für dieses Problem ist ein einfaches von Drupal 8 beigesteuertes Modul: Nach der Anmeldung umleiten . Das Modul finden Sie hier:

https://www.drupal.org/project/redirect_after_login

Wie die Beschreibung zeigt, handelt es sich um ein einfaches, fokussiertes Modul, das von der Drupal-Sicherheitsrichtlinie abgedeckt wird.

bkudrle
quelle
1

/**
 * hook_user_login Redirect to English language whenever admin login
 **/
function modulename_user_login($account) {
  // We want to redirect user on login.
  $response = new Symfony\Component\HttpFoundation\RedirectResponse("/en/admin/config");
  $response->send();
  return;
}
Manikandan
quelle
1

Ich benutze das folgende Snippet ziemlich oft, also dachte ich, ich würde es teilen. Sie können verschiedene Weiterleitungen hinzufügen, je nachdem, welche Rolle der Benutzer hat.

use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * Redirect on login.
 */
function MYMODULE_user_login($account) {
  $roles = $account->getRoles();
  if(in_array('webmaster', $roles)) {
    $response = new RedirectResponse('/admin/content');
    $response->send();
  }
}
Stef Van Looveren
quelle