Odpowiedzi:
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'));
}
}
else
tutaj dzieje ? Utrzymanie istniejącego przekierowania?
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\Url
klasy, 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.
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.
ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION
W 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.
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\RedirectResponseSubscriber
pod koniec przetwarzania odpowiedzi).
* Każdy formularz, który wywołuje hook_user_login (user_login_finalize ()) i nie wywołuje ręcznie FormState :: setResponse () .
mymodule.dashboard
to 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/…
Możesz to po prostu zrobić za pomocą Reguł
Reaguj: Po zalogowaniu się użytkownika
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.
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.
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ń.
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_alter
wszystkich formularzy logowania i dodać niestandardową procedurę obsługi przesyłania, która ustawia przekierowanie na obiekcie stanu formularza.
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
Wystarczy dodać destination
parametr do adresu URL logowania.
Przykład:http://example.com/user/login?destination=/my-page
Jeśli robisz to dla stron 403 (odmowa dostępu), użyj następującego modułu:
https://www.drupal.org/project/redirect_403_to_login_page
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();
}
}
Użyj dowolnego z tych modułów:
https://www.drupal.org/project/login_redirect
LUB
https://www.drupal.org/project/login_destination
Twoje zdrowie
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.
https://www.drupal.org/project/redirect
Skonfiguruj powyższy moduł, aby przekierowywać
/ user / login to / user / login? destination = 'CUSTOM_NODE_PATH'
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.
/**
* 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;
}
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
$form_state->setRedirect('mymodule.dashboard);