Przekieruj po zalogowaniu użytkownika

14

Chciałbym przekierowywać użytkowników po zalogowaniu. Czy można użyć hook_user_login()tego przekierowania? Jak dodać parametr przekierowania?

John Chan
źródło

Odpowiedzi:

19

Musisz zmienić formularz logowania i dodać moduł obsługi przesyłania, który zajmie się przekierowaniem. Nie możesz użyć $form_state->setRedirectUrl()bezpośrednio w formularzu alter, ponieważ zostanie on zastąpiony przez 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
źródło
4
Jak opisano w @kiamlaluno, można również użyć$form_state->setRedirect('mymodule.dashboard);
Filipe Miguel Fonseca
3
Wyjaśnij użytkownikom, którzy podążają za tą odpowiedzią, co powinien / powinien zrobić mymodule.dashboard. Jak zmienić to na <front>, tylko dla przykładu. Ponieważ pulpit użytkownika jest domyślnym przekierowaniem po zalogowaniu, ten przykład tutaj jest bezużyteczny. Nowy użytkownik nie wie, które części zmienić i jak przekierować.
nilsun
1
Aby przekierować na pierwszą stronę, możesz użyć powyższego przykładu, ale zmień wiersz, który generuje obiekt $ url na $ url = Url :: fromUri ('internal: /');
oknate
1
Nie rozumiem, co się elsetutaj dzieje ? Utrzymanie istniejącego przekierowania?
user1359,
1
musisz użyć use Drupal \ Core \ Url; aby działał poprawnie
Jignesh Rawal
16

Przekierowywanie użytkowników po zalogowaniu się na stronie Drupal 8 nie różni się od tego, jak to zrobiono na Drupal 7, z wyjątkiem tego, że kod musi zostać dostosowany do Drupal 8.

W szczególności:

  • hook_user_login()nie jest używany do przekierowywania użytkowników po zalogowaniu, po prostu dlatego, że przekierowanie użytkowników w tym zaczepie uniemożliwiłoby hook_user_login()wywołanie innych implementacji.
  • Prawidłowym sposobem przekierowania użytkowników jest dodanie modułu obsługi przesyłania formularzy do formularza logowania, który używa kodu podobnego do poniższego.

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

    Zauważ, że user.page to nazwa routingu dla ścieżki Drupal, do której chcesz przekierować użytkownika.
    Jeśli masz instancję Drupal\Core\Urlklasy, możesz również użyć następującego kodu.

    $form_state->setRedirectUrl($url);

    Pamiętaj, że pierwsza metoda jest lepsza, gdy przekierowujesz użytkowników na stronę w tej samej witrynie, w której się zalogowali; druga metoda jest zwykle używana do przekierowywania użytkowników za pomocą zewnętrznego adresu URL.

kiamlaluno
źródło
11

możesz użyć hook_user_login i spróbować przekierować nayourpath

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

Możesz także użyć modułu Reguły , ale NIE ma jeszcze stabilnej wersji dla Drupal 8.

Yusef
źródło
Dobre eleganckie rozwiązanie, działało dla mnie w Drupal 8.1.
Alexei Rayu
3
ERR_RESPONSE_HEADERS_MULTIPLE_LOCATIONW pewnych okolicznościach otrzymywałem błędy związane z powyższym - sugeruję zastąpienie return;go exit;, aby przekierowanie - które ustawia nagłówki - było ostatnią rzeczą do wykonania.
2
Funkcja hook_user_login () jest wywoływana przed programami obsługi przesyłania, aby zapobiec ich wywołaniu. Poniższa odpowiedź Yogesh'a jest lepszym sposobem na zrobienie tego.
imclean
9

Trochę za późno na imprezę, ale zgodnie z https://www.drupal.org/node/2068293#comment-11712455 możesz ustawić miejsce docelowe w hook_user_login (), aby przekierowywać na końcu procesu logowania.

to znaczy

/**
 * 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()
      );
    }
  }
}

Użycie FormState :: setRedirect () zgodnie z innymi odpowiedziami prawdopodobnie obejmie przypadki użycia przez większość ludzi i jest potencjalnie „prawidłową” odpowiedzią, jednak użycie parametru zapytania docelowego z hook_user_login oznacza, że każda przesłana forma *, która loguje użytkownika, przekieruje, ale bez ingerencji lub wcześniejszej znajomości jakiejkolwiek innej części formularza / zapytania.

tzn. nadal będzie działał z niestandardowym formularzem logowania, a użycie miejsca docelowego nie zatrzyma żadnych innych przechwyceń (jest realizowane przez \Drupal\Core\EventSubscriber\RedirectResponseSubscriberpod koniec przetwarzania odpowiedzi).

* Każdy formularz, który wywołuje hook_user_login (user_login_finalize ()) i nie wywołuje ręcznie FormState :: setResponse () .

Sut3kh
źródło
1
Ma to tę zaletę, że działa, jeśli uwierzytelnianie odbywa się na podstawie innej niż formularz logowania. Ale czy to koliduje z innymi implementacjami hook_user_login z innych modułów?
Jonathan
1
@Jonathan Nie, ustawia tylko miejsce docelowe i nie wykonuje wczesnego żądania-> send () ani niczego (np. D7 drupal_goto), pozwoli wszystkim innym hakom, tworzeniu wywołań zwrotnych itp. Działać normalnie, zanim zostanie wykonane . Tak właśnie robi standardowe przekierowanie logowania Drupal .
Sut3kh
1
Wyjaśnij użytkownikom, którzy podążają za tą odpowiedzią, co powinien / powinien zrobić mymodule.dashboard. Jak zmienić to na <front>, tylko dla przykładu. Ponieważ pulpit użytkownika jest domyślnym przekierowaniem po zalogowaniu, ten przykład tutaj jest bezużyteczny. Nowy użytkownik nie wie, które części zmienić i jak przekierować.
nilsun
3
@ nilsun mymodule.dashboardto nazwa trasy, którą można zastąpić dowolną nazwą trasy (tj. \Drupal\Core\Url::fromRoute('<front>')->toString()lub \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 123])->toString()). Aby uzyskać więcej informacji, zobacz drupal.org/docs/8/api/routing-system/routing-system-overview i api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/…
Sut3kh
2
To łamie reset hasła, więc głosuję w dół na odpowiedź. (Utworzenie procedury obsługi przesyłania formularzy dla user_login_form, jak sugerowano w innej odpowiedzi, działa.)
hansfn
7

Możesz to po prostu zrobić za pomocą Reguł

Reaguj: Po zalogowaniu się użytkownika

  • Dodaj akcję: Przekieruj >>, a następnie użyj parametru lub wpisz swój adres URL.
Shrikant Nakade
źródło
3
Głównym zastrzeżeniem jest to, że Zasady są jeszcze w wersji wstępnej ALPHA dla Drupala 8, więc uważaj, jeśli potrzebujesz stabilności na swojej stronie
Philippe Gilbert
1
Reguły psują system logowania, gdy strona przekierowuje na stronę po zalogowaniu użytkownika. Uwaga
InspiredCoder
6

Możesz także zmienić formularz logowania użytkownika i dodać własny niestandardowy moduł obsługi przesyłania, aby ustawić przekierowanie $ form_state, zamiast przekierowywać użytkownika bezpośrednio do niestandardowego adresu URL za pomocą hook_user_login .

<?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');
}

Dodanie go w przekierowaniu $ form_state sprawi, że inne wywołania handlerów / haczyków logowania zostaną wywołane.

Podobnie jak Drupal7, nie możemy bezpośrednio ustawić $ form_state ['redirect'], ponieważ $ form_state jest teraz obiektem klasy. Kasa FormState :: setRedirect () w celu uzyskania dalszych szczegółów.

Jogesh
źródło
6

W D8 możesz użyć do tego celu domyślnego modułu strony użytkownika .

Ten moduł pozwala dostosować miejsce docelowe, do którego użytkownik jest przekierowywany po zalogowaniu lub wylogowaniu. Możesz dostosować według ról lub poszczególnych użytkowników.

Pallavi Chaudhury
źródło
1
Działa, ale nie bierze pod uwagę linków do resetowania hasła, gdy użytkownik używa linku jednorazowego do ustawienia hasła, przekierowuje go na stronę ustawioną w tym module, a nie na konto użytkownika.
Sorin
1
Ten moduł wciąż przerywa resetowanie hasła, więc głosuję w dół za odpowiedzią. Zobacz drupal.org/project/user_default_page/issues/2991916 (Tworzenie procedury obsługi przesyłania formularza dla user_login_form zgodnie z sugestią w innej odpowiedzi działa.)
hansfn
4

Jest to prosty moduł do wykonania tego, który jest zgodny z Drupal 8. Nazywa się to Domyślna strona użytkownika .

Moduł pozwala dostosować miejsce docelowe, do którego użytkownik jest przekierowywany po zalogowaniu lub wylogowaniu. Możesz dostosować według ról lub poszczególnych użytkowników. I dostosuj konfigurowalne komunikaty drupal dla tych działań.

Pallavi Chaudhury
źródło
3

hook_user_login() nie działa na przekierowanie, jest używany, jeśli chcesz zrobić coś z użytkownikiem, gdy się zaloguje. Rdzeń Fx sugeruje użytkownikom ustawienie lokalnej strefy czasowej, jeśli nie jest ustawiona.

Zamiast tego musisz użyć hook_form_alterwszystkich formularzy logowania i dodać niestandardową procedurę obsługi przesyłania, która ustawia przekierowanie na obiekcie stanu formularza.

googletorp
źródło
2

Wyświetlam formularz logowania we własnym kontrolerze. W ten sposób można manipulować formularzem (a więc przekierowywać użytkownika po zalogowaniu) bez haków innych niż OO:

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

Zmień trasę „proreos.home” na dowolne miejsce docelowe.

pozdrowienia

Rainer

Rainer Feike
źródło
2

Często używam następującego fragmentu kodu, więc pomyślałem, że go podzielę. Możesz dodać różne przekierowania w zależności od roli użytkownika.

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
źródło
1

Do przekierowania możesz użyć modułu logintoboggan . Ma inne konfiguracje, które mogą być przydatne, jeśli chcesz innych funkcji, takich jak logowanie przy użyciu nazw użytkowników.

nitvirus
źródło
2
Dobra odpowiedź dla D7, ale to pytanie jest oznaczone jako D8 i nie ma jeszcze wersji Drupal 8 Logintoboggan.
Kelley Curry
1

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

  1. Zainstaluj powyższy moduł
  2. Dodaj niestandardową ścieżkę do adresu URL jako parametr docelowy w adresie URL
  3. Skonfiguruj powyższy moduł, aby przekierowywać

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

    • Chciałem użyć modułu r4032login , aby umożliwić uwierzytelnionym użytkownikom dostęp do danej strony, gdy kopiują / wklejają adres URL lub używają na przykład hiperłącza z word / excel.
    • Inne moduły „przekierowania logowania” zastąpiłyby tę funkcjonalność i pozwoliłyby użytkownikom na lądowanie na skonfigurowanej pojedynczej stronie, nawet jeśli parametry docelowe są zawarte w adresie URL
Abhi
źródło
1

Inną opcją dotyczącą tego problemu jest prosty moduł Drupal 8: Przekieruj po zalogowaniu . Moduł można znaleźć tutaj:

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

Jak pokazuje opis, jest to prosty, skoncentrowany moduł, który jest objęty polityką bezpieczeństwa Drupal.

bkudrle
źródło
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
źródło
0

Pracowałem nad sposobem obejścia innych rzeczy, które zależą od hook_user_login, ponieważ wiele nowych opcji psuje się w nowszych wersjach 8. Niektóre inne moduły przekierowujące wykonują dużo pracy nóg, która albo nie jest już istotna i / lub po prostu nieuporządkowane zasoby. Złożyłem tę prostą logikę w niestandardowym module do obsługi procesów logowania:

function hook_user_login( UserInterface $account ) {
  // Doing checks to see if the login is from an HTML origin or not.
  // Could be from RESTful request to logins
  $request = \Drupal::request();
  if ($request->getRequestFormat() !== 'html') {
    // default
    return;
  }

  // Get the destination to see where the login request is going.
  // This is useful to check for interactions from user creations.
  $destination = $request->query->get('destination');

  // Check the destination. If the destination will result in a re-direct 
  // to your homepage (here statically defined, but could be programmatic)
  // then you can force re-direct to a different page. This is the URL defined
  // in config > system > basic site settings.
  if ($destination && $destination === '/whatever-homepage-uri-is') {
    // Regular login, send to alternate welcome page
    $response = new RedirectResponse('/welcome');
    $response->send();
    exit;
  }

  // default
  return;
}

Korzystam z tego z powodzeniem z Drupal 8.8.3 i nie psuje moich żądań logowania REST z innego zbudowanego przeze mnie modułu, przekierowuje poprawnie na nowe konta, a następnie przekierowuje na inną stronę przy regularnym logowaniu na stronie.

W pobliżu

Ron
źródło