用户登录后重定向


14

我想在用户登录后将其重定向。是否可以使用hook_user_login()进行重定向?如何添加重定向参数?

Answers:


19

您需要更改登录表单并添加一个提交处理程序,它将负责重定向。您不能$form_state->setRedirectUrl()直接在alter格式中使用,因为它将被覆盖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'));
  }
}

4
如@kiamlaluno所述,您也可以使用$form_state->setRedirect('mymodule.dashboard);
Filipe Miguel Fonseca

3
请解释遵循此答案的用户mymodule.dashboard应该/将要做什么。仅作为示例,如何将其更改为<front>。由于用户仪表板是登录后的默认重定向,因此此处的示例无用。新用户不知道要更改哪些部分以及如何进行重定向。
nilsun

1
要重定向到首页,您可以使用上面的示例,但是将生成$ url对象的行更改为$ url = Url :: fromUri('internal:/');
oknate

1
我不明白else这里发生了什么?维持现有的重定向?
user1359 '18

1
您必须使用use Drupal \ Core \ Url; 使它正常工作
Jignesh Rawal

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

您也可以使用Rules模块,但是Drupal 8还没有稳定版本。


一个很好的优雅解决方案,在Drupal 8.1中为我工作。
Alexei Rayu '16

3
ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION在上述情况下,我在某些情况下会出现错误-我建议替换return;exit;,以确保重定向(设置标头)是最后要执行的操作。

2
在提交处理程序之前调用hook_user_login(),这样可以防止它们被调用。Yogesh在下面的回答是一种更好的方法。
干净的

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一起使用意味着登录用户的任何表单提交 *都会重定向,但是不会干扰或事先不了解表格/要求的任何其他部分。

也就是说,它仍然可以与自定义登录表单一起使用,并且使用destination不会停止任何其他挂接(由\Drupal\Core\EventSubscriber\RedirectResponseSubscriber响应处理结束时实现 )。

*任何表单提交都会调用hook_user_login(user_login_finalize()),并且不会手动调用FormState :: setResponse()


1
如果身份验证是通过登录表单以外的方式进行的,则具有工作的优势。但这是否会干扰其他模块的其他hook_user_login实现?
乔纳森

1
@Jonathan不,它只设置目标,不执行早期的request-> send()或其他任何操作(例如d7 drupal_goto),它将允许所有其他钩子,表单回调等在正常运行之前运行。这就是标准的drupal登录重定向的方式。
Sut3kh

1
请解释遵循此答案的用户mymodule.dashboard应该/将要做什么。仅作为示例,如何将其更改为<front>。由于用户仪表板是登录后的默认重定向,因此此处的示例无用。新用户不知道要更改哪些部分以及如何进行重定向。
nilsun

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-overviewapi.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/...
Sut3kh

2
这样会破坏密码重置,因此我拒绝了答案。(按照另一个答案的建议,为user_login_form创建表单提交处理程序。)
hansfn

7

您只需使用规则即可

反应:用户登录后

  • 添加操作:重定向>>,然后使用参数或输入您的网址。

3
主要警告是规则仍然在Drupal 8的预发布ALPHA中,因此,如果您需要网站上的稳定性,请多加注意
Philippe Gilbert

1
当用户登录后网站重定向到页面时,Rule破坏了登录系统。当心
InspiredCoder

6

您还可以更改用户登录表单并添加自己的自定义提交处理程序以设置$ form_state redirect,而不是使用hook_user_login将用户直接重定向到您的自定义URL 。

<?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现在是类对象。签出FormState :: setRedirect()以获得更多详细信息。


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 core建议用户设置本地时区(如果未设置)。

相反,您需要hook_form_alter在所有登录表单上使用并添加一个自定义的提交处理程序,以在表单状态对象上设置重定向。


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”路线更改为您需要的任何目的地。

问候

雷纳



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模块进行重定向。它具有其他配置,如果您需要其他功能(例如使用用户名登录),可能会很有用。


2
D7的好答案,但是这个问题被标记为D8,并且还没有Drupal 8版本的Logintoboggan。
凯利·库里

1

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

  1. 安装以上模块
  2. 在网址中添加自定义网址路径作为目标参数
  3. 因此,将上述模块配置为从

    / user /登录到/ user / login?destination ='CUSTOM_NODE_PATH'

    • 想要使用r4032login模块来允许经过身份验证的用户访问相关页面,例如当他们复制/粘贴url或使用word / excel中的超链接时。
    • 其他“登录重定向”模块将覆盖此功能,并且即使目标参数包含在url中,也仅允许用户登陆已配置的单个页面。


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

0

``我正在研究一种方法,以解决依赖于hook_user_login的其他问题,因为在较新版本的8中其他许多选项都被打破了。其他一些重定向模块做了很多无关紧要的工作,或者/或完全浪费资源。我将以下简单逻辑组合到用于处理登录过程的自定义模块中:

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

我已经在Drupal 8.8.3中成功使用了它,它不会中断我构建的另一个模块的REST登录请求,可以正确地重定向以创建新帐户,然后在常规站点登录时重定向到其他页面。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.