Перенаправление после входа пользователя

14

Я хотел бы перенаправить пользователей после входа в систему. Можно ли использовать hook_user_login()для перенаправления? Как добавить параметр для перенаправления?

Джон Чан
источник

Ответы:

19

Вам нужно изменить форму входа и добавить обработчик отправки, который позаботится о перенаправлении. Вы не можете использовать $form_state->setRedirectUrl()непосредственно в форме изменить, так как она будет перезаписана 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
источник
4
Как описывает @kiamlaluno, можно также использовать$form_state->setRedirect('mymodule.dashboard);
Филипе Мигель Фонсека
3
Пожалуйста, объясните пользователям, которые следуют этому ответу, что mymodule.dashboard должен / будет делать. Как изменить это на <front>, просто для примера. Поскольку панель инструментов пользователя является перенаправлением по умолчанию после входа в систему, этот пример здесь бесполезен. Новый пользователь не знает, какие части изменить и как его перенаправить.
nilsun
1
Чтобы перенаправить на главную страницу, вы можете использовать приведенный выше пример, но измените строку, генерирующую объект $ url, на $ url = Url :: fromUri ('internal: /');
17
1
Я не понимаю, что elseздесь происходит? Поддержание существующего перенаправления?
user1359
1
вы должны использовать использовать Drupal \ Core \ Url; чтобы заставить его работать правильно
Джинеш Равал
16

Перенаправление пользователей после входа на сайт Drupal 8 не отличается от того, как это было сделано в Drupal 7, за исключением того, что код должен быть адаптирован для Drupal 8.

Особенно:

  • hook_user_login()не используется для перенаправления пользователей после входа в систему, просто потому, что перенаправление пользователей в этом хуке остановит вызов других hook_user_login()реализаций.
  • Правильный способ перенаправления пользователей - добавление обработчика отправки формы в форму входа, в которой используется код, подобный следующему.

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

    Обратите внимание, что user.page - это имя маршрута для пути Drupal, куда вы хотите перенаправить пользователя.
    Если у вас есть экземпляр Drupal\Core\Urlкласса, вы также можете использовать следующий код.

    $form_state->setRedirectUrl($url);

    Помните, что первый способ предпочтителен, когда вы перенаправляете пользователей на страницу того же сайта, на котором они вошли; второй метод обычно используется для перенаправления пользователей с использованием внешнего URL.

киамлалуно
источник
11

Вы можете использовать hook_user_login и попытаться перенаправить наyourpath

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

Также вы можете использовать модуль Правила , но пока нет стабильной версии для Drupal 8.

Юсеф
источник
Хорошее элегантное решение, сработало для меня в Drupal 8.1.
Алексей Раю
3
Я получал ERR_RESPONSE_HEADERS_MULTIPLE_LOCATIONошибки в определенных обстоятельствах с вышеупомянутым - я предлагаю заменить return;на exit;, чтобы гарантировать, что перенаправление - которое устанавливает заголовки - является последним, что должно быть выполнено.
2
hook_user_login () вызывается перед обработчиками отправки, поэтому это будет препятствовать их вызову. Ответ Йогеша ниже - лучший способ сделать это.
августа
9

Немного опоздал на вечеринку, но согласно https://www.drupal.org/node/2068293#comment-11712455 вы можете установить пункт назначения в hook_user_login () для перенаправления в конце обработки входа в систему.

т.е.

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

Использование FormState :: setRedirect () в соответствии с другими ответами, вероятно, охватит случаи использования большинства людей и, возможно, является «правильным» ответом, однако использование параметра запроса назначения с hook_user_login означает, что любая форма submit *, которая регистрирует пользователя, будет перенаправлять, но без вмешательства или предварительного знания любой другой части формы / запроса.

то есть он все еще будет работать с пользовательской формой входа в систему, и использование пункта назначения не останавливает какие-либо другие ловушки (это реализуется \Drupal\Core\EventSubscriber\RedirectResponseSubscriberв конце обработки ответа).

* Любая форма отправки, которая вызывает hook_user_login (user_login_finalize ()) и не вызывает вручную FormState :: setResponse () .

Sut3kh
источник
1
Это имеет преимущество работы, если аутентификация происходит из чего-то другого, кроме формы входа в систему. Но мешает ли это другим реализациям hook_user_login из других модулей?
Джонатан
1
@Jonathan Нет, он только устанавливает пункт назначения и не выполняет ранний запрос-> send () или что-либо еще (например, как d7 drupal_goto), он позволит всем другим хукам, обратным вызовам форм и т. Д. Работать как обычно, прежде чем он будет обработан , Вот как это делает стандартное перенаправление входа в систему drupal .
Сут3х
1
Пожалуйста, объясните пользователям, которые следуют этому ответу, что mymodule.dashboard должен / будет делать. Как изменить это на <front>, просто для примера. Поскольку панель инструментов пользователя является перенаправлением по умолчанию после входа в систему, этот пример здесь бесполезен. Новый пользователь не знает, какие части изменить и как его перенаправить.
Нильсун
3
@nilsun mymodule.dashboard- это имя маршрута и может быть заменено любым именем маршрута (т.е. \Drupal\Core\Url::fromRoute('<front>')->toString()или \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 123])->toString()). Для получения дополнительной информации см. Drupal.org/docs/8/api/routing-system/routing-system-overview и api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/…
Sut3kh
2
Это нарушает сброс пароля, поэтому я не голосую за ответ. (Создание обработчика
отправки
7

Вы можете просто сделать это, используя правила

Реагировать на: после того, как пользователь вошел в систему

  • Добавить действие: Перенаправить >>, затем использовать параметр или ввести свой URL.
Шрикант Накаде
источник
3
Основное предостережение заключается в том, что Правила все еще находятся в предварительной версии ALPHA для Drupal 8, поэтому будьте осторожны, если вам нужна стабильность на вашем сайте
Филипп Гилберт
1
Правила портят систему входа в систему, когда сайт перенаправляет на страницу после входа пользователя. Остерегайтесь
InspiredCoder
6

Вы также можете изменить форму входа пользователя и добавить свой собственный обработчик отправки, чтобы установить перенаправление $ form_state, вместо прямого перенаправления пользователя на ваш пользовательский URL с помощью 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');
}

Добавление его в перенаправление $ form_state обеспечит вызов других обработчиков отправки / хуков входа в систему.

Как и Drupal7, мы не можем установить $ form_state ['redirect'] напрямую, потому что $ form_state теперь является объектом класса. Checkout FormState :: setRedirect () для получения более подробной информации.

Yogesh
источник
6

В D8 вы можете использовать пользовательский модуль страницы по умолчанию для этой цели.

Этот модуль позволяет вам настроить пункт назначения, на который перенаправляется пользователь после входа или выхода из системы. Вы можете настроить по ролям или отдельным пользователям.

Паллави Чаудхури
источник
1
Работает, но не учитывает ссылки для сброса пароля, когда пользователь использует одноразовую ссылку для установки своего пароля, он перенаправляет их на страницу, установленную в этом модуле, а не на учетную запись пользователя.
Сорин
1
Этот модуль все еще нарушает сброс пароля, поэтому я отказываюсь от ответа. См. Drupal.org/project/user_default_page/issues/2991916 (Создание обработчика отправки формы для user_login_form, как предлагается в другом ответе, работает.)
hansfn
4

Для этого существует простой модуль, совместимый с Drupal 8. Он называется User Default Page .

Модуль позволяет настроить пункт назначения, на который перенаправляется пользователь после входа или выхода из системы. Вы можете настроить по ролям или отдельным пользователям. И настроить настраиваемые сообщения drupal для этого действия.

Паллави Чаудхури
источник
3

hook_user_login() не работает для перенаправления, он используется, если вы хотите что-то сделать с пользователем, когда он входит в систему. Ядро Fx предлагает пользователям установить местный часовой пояс, если он не установлен.

Вместо этого вам нужно использовать hook_form_alterво всех формах входа в систему и добавить пользовательский обработчик отправки, который устанавливает перенаправление для объекта состояния формы.

googletorp
источник
2

Я отображаю форму входа в свой собственный контроллер. Таким образом, можно манипулировать формой (и, таким образом, перенаправлять пользователя после входа в систему) без хуков, не относящихся к 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;

Измените маршрут «proreos.home» на нужный вам пункт назначения.

С уважением

Rainer

Райнер Фейке
источник
2

Просто добавьте destinationпараметр в логин URL.
Пример:http://example.com/user/login?destination=/my-page

Если вы делаете это для 403 страниц (доступ запрещен), используйте следующий модуль:
https://www.drupal.org/project/redirect_403_to_login_page

Потерянный кодер
источник
2

Я использую следующий фрагмент довольно часто, поэтому я решил поделиться им. Вы можете добавлять различные перенаправления в зависимости от роли пользователя.

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();
  }
}
Стеф Ван Луверен
источник
1

Вы можете использовать модуль logintoboggan для перенаправления. Он имеет другие конфигурации, которые могут быть полезны, если вам нужны другие функции, такие как вход в систему с использованием имен пользователей.

nitvirus
источник
2
Хороший ответ для D7, но этот вопрос помечен D8, и еще нет версии Logintoboggan для Drupal 8.
Келли Карри
1

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

  1. Установите вышеуказанный модуль
  2. Добавить пользовательский путь URL в качестве параметра назначения в URL
  3. Итак, настройте вышеупомянутый модуль для перенаправления с

    / user / войти в систему / user / login? destination = 'CUSTOM_NODE_PATH'

    • Хотел использовать модуль r4032login, чтобы позволить аутентифицированным пользователям получать доступ к соответствующей странице, когда они копируют / вставляют URL-адрес или используют, например, гиперссылку из word / excel.
    • Другие модули 'перенаправление входа в систему' переопределяют эту функциональность и позволяют пользователям заходить на настроенную отдельную страницу, даже если параметры назначения включены в URL
Аби
источник
1

Другим вариантом, специально предназначенным для этой проблемы, является простой модуль для Drupal 8: Redirect After Login . Модуль можно найти здесь:

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

Как видно из описания, это простой, сфокусированный модуль, на который распространяется политика безопасности Drupal.

bkudrle
источник
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
источник