Redireccionar después de iniciar sesión

14

Me gustaría redirigir a los usuarios después de que inicien sesión. ¿Es posible usar hook_user_login()para hacer la redirección? ¿Cómo agrego el parámetro para la redirección?

John Chan
fuente

Respuestas:

19

Debe modificar el formulario de inicio de sesión y agregar un controlador de envío que se encargará de la redirección. No puede usar $form_state->setRedirectUrl()directamente en el formulario alter, ya que será sobrescrito por 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
fuente
44
Según lo descrito por @kiamlaluno, también se puede usar$form_state->setRedirect('mymodule.dashboard);
Filipe Miguel Fonseca
3
Explique a los usuarios que siguen esta respuesta lo que mymodule.dashboard debería / haría. Cómo cambiar eso a <front>, solo por un ejemplo. Dado que el panel de usuario es la redirección predeterminada después de iniciar sesión, este ejemplo aquí es inútil. El nuevo usuario no sabe qué partes alterar y cómo para su redirección.
nilsun
1
Para redirigir a la página principal, puede usar el ejemplo anterior pero cambiar la línea que genera el objeto $ url a $ url = Url :: fromUri ('internal: /');
Oknate
1
No entiendo lo que está pasando elseaquí. Mantener una redirección existente?
usuario1359
1
tienes que usar use Drupal \ Core \ Url; para que funcione correctamente
Jignesh Rawal
16

La redirección de usuarios después de iniciar sesión en un sitio de Drupal 8 no es diferente de cómo se hizo en Drupal 7, excepto que el código debe adaptarse para Drupal 8.

En particular:

  • hook_user_login()no se utiliza para redirigir a los usuarios después de que inicien sesión, simplemente por el hecho de que redirigir a los usuarios en ese enlace evitaría que hook_user_login()se invoquen otras implementaciones.
  • La forma correcta de redirigir a los usuarios es agregar un controlador de envío de formularios al formulario de inicio de sesión que utiliza un código similar al siguiente.

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

    Tenga en cuenta que user.page es el nombre de ruta para la ruta de Drupal donde desea que se redirija al usuario.
    Si tiene una instancia de la Drupal\Core\Urlclase, también puede usar el siguiente código.

    $form_state->setRedirectUrl($url);

    Tenga en cuenta que el primer método es preferible cuando redirige a los usuarios a una página en el mismo sitio en el que iniciaron sesión; El segundo método se utiliza normalmente para redirigir a los usuarios utilizando una URL externa.

kiamlaluno
fuente
11

puede usar hook_user_login e intentar redirigir ayourpath

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

También puede usar el módulo Reglas , pero todavía NO hay una versión estable para Drupal 8.

Yusef
fuente
Una buena solución elegante, funcionó para mí en Drupal 8.1.
Alexei Rayu
3
Obtuve ERR_RESPONSE_HEADERS_MULTIPLE_LOCATIONerrores en ciertas circunstancias con lo anterior, sugiero reemplazar return;con exit;, para asegurar que la redirección, que establece encabezados, es lo último que se ejecuta.
2
Se llama a hook_user_login () antes de los controladores de envío, por lo que esto evitaría que se les llame. La respuesta de Yogesh a continuación es una mejor manera de hacer esto.
impecable
9

Un poco tarde para la fiesta, pero según https://www.drupal.org/node/2068293#comment-11712455 puede establecer el destino en hook_user_login () para redirigir al final del proceso de inicio de sesión.

es decir

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

El uso de FormState :: setRedirect () según las otras respuestas probablemente cubrirá los casos de uso de la mayoría de las personas y es potencialmente la respuesta 'correcta', sin embargo, usar el parámetro de consulta de destino con hook_user_login significa que cualquier envío de formulario * que inicie sesión en el usuario redirigirá pero sin interferencia o conocimiento previo de cualquier otra parte del formulario / solicitud.

es decir, seguirá funcionando con un formulario de inicio de sesión personalizado y el uso del destino no detiene ningún otro enlace (se implementa \Drupal\Core\EventSubscriber\RedirectResponseSubscriberal final del proceso de respuesta).

* Cualquier envío de formulario que invoque hook_user_login (user_login_finalize ()) y no llame manualmente a FormState :: setResponse () .

Sut3kh
fuente
1
Esto tiene la ventaja de funcionar si la autenticación se realiza desde algo que no sea un formulario de inicio de sesión. ¿Pero esto interfiere con otras implementaciones de hook_user_login de otros módulos?
Jonathan
1
@ Jonathan No, solo establece el destino y no realiza una solicitud anticipada-> send () ni nada (es decir, como d7 drupal_goto), permitirá que todos los otros ganchos, devoluciones de llamada, etc. se ejecuten normalmente antes de que se actúe . Así es como lo hace la redirección de inicio de sesión estándar de drupal .
Sut3kh
1
Explique a los usuarios que siguen esta respuesta lo que mymodule.dashboard debería / haría. Cómo cambiar eso a <front>, solo por un ejemplo. Dado que el panel de usuario es la redirección predeterminada después de iniciar sesión, este ejemplo aquí es inútil. El nuevo usuario no sabe qué partes alterar y cómo para su redirección.
nilsun
3
@nilsun mymodule.dashboardes el nombre de la ruta y se puede reemplazar con cualquier nombre de ruta (es decir, \Drupal\Core\Url::fromRoute('<front>')->toString()o \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 123])->toString()). Para obtener más información, consulte drupal.org/docs/8/api/routing-system/routing-system-overview y api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/…
Sut3kh
2
Esto rompe el restablecimiento de la contraseña, así que rechazo la respuesta. (La creación de un controlador de envío de formularios para user_login_form como se sugiere en otra respuesta funciona)
hansfn
7

Simplemente puede hacerlo usando Reglas

Reaccionar: después de que el usuario haya iniciado sesión

  • Agregar acción: Redirigir >> luego use un parámetro o escriba su url.
Shrikant Nakade
fuente
3
La advertencia principal sobre esto es que las Reglas todavía están en prelanzamiento ALPHA para Drupal 8, así que tenga cuidado si necesita estabilidad en su sitio web
Philippe Gilbert
1
Las reglas desordenan el sistema de inicio de sesión cuando el sitio redirige a una página después de que el usuario inicia sesión. Cuidado
InspiredCoder
6

También puede modificar el formulario de inicio de sesión del usuario y agregar su propio controlador de envío personalizado para establecer la redirección de $ form_state, en lugar de redirigir directamente al usuario a su URL personalizada utilizando 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');
}

Al agregarlo en $ form_state redirect se asegurará de que se llame a los otros controladores de envío / ganchos de inicio de sesión.

Al igual que Drupal7, no podemos establecer $ form_state ['redirect'] directamente, porque $ form_state ahora es un objeto de clase. Checkout FormState :: setRedirect () para más detalles.

Yogesh
fuente
6

En D8, puede usar el módulo de página predeterminado del usuario para este propósito.

Este módulo le permite personalizar el destino al que se redirige a un usuario después de iniciar o cerrar sesión. Puede personalizar por roles o usuarios individuales.

Pallavi Chaudhury
fuente
1
Funciona pero no tiene en cuenta los enlaces de restablecimiento de contraseña, cuando el usuario usa el enlace único para establecer su contraseña, los redirige a la página que configuró en este módulo y no a la cuenta de usuario.
Sorin
1
Este módulo todavía rompe el restablecimiento de contraseña, así que rechazo la respuesta. Consulte drupal.org/project/user_default_page/issues/2991916 (Crear un controlador de envío de formularios para user_login_form como se sugiere en otra respuesta funciona).
hansfn
4

Hay un módulo simple para hacer esto que es compatible con Drupal 8. Se llama Página predeterminada del usuario .

El módulo le permite personalizar el destino al que se redirige a un usuario después de iniciar o cerrar sesión. Puede personalizar por roles o usuarios individuales. Y personalice los mensajes configurables de drupal para estas acciones.

Pallavi Chaudhury
fuente
3

hook_user_login() no funciona para la redirección, se usa si desea hacer algo con el usuario cuando inicia sesión. Fx core sugiere a los usuarios que configuren la zona horaria local si no está configurada.

En su lugar, debe usar hook_form_altertodos los formularios de inicio de sesión y agregar un controlador de envío personalizado que establezca la redirección en el objeto de estado del formulario.

googletorp
fuente
2

Estoy mostrando el formulario de inicio de sesión en mi propio controlador. De esa manera, es posible manipular el formulario (y así redirigir al usuario después de iniciar sesión) sin los enlaces que no son 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;

Cambie la ruta 'proreos.home' a cualquier destino que necesite.

Saludos

Rainer

Rainer Feike
fuente
2

Utilizo bastante el siguiente fragmento, así que pensé en compartirlo. Puede agregar diferentes redirecciones dependiendo del rol que tenga el usuario.

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
fuente
1

Puede usar el módulo logintoboggan para la redirección. Tiene otras configuraciones que pueden ser útiles si desea otras funcionalidades como iniciar sesión con nombres de usuario.

nitvirus
fuente
2
Buena respuesta para D7, pero esta pregunta está etiquetada como D8, y todavía no hay una versión Drupal 8 de Logintoboggan.
Kelley Curry
1

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

  1. Instale el módulo anterior
  2. Agregue una ruta de URL personalizada como parámetro de destino en la url
  3. Entonces, configure el módulo anterior para redirigir desde

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

    • Quería usar el módulo r4032login para permitir que los usuarios autenticados accedan a la página en cuestión, cuando copian / pegan la url o usan un hipervínculo de word / excel, por ejemplo.
    • Otros módulos de 'redirección de inicio de sesión' anularían esta funcionalidad y solo permitirían a los usuarios aterrizar en una sola página configurada incluso cuando los parámetros de destino estén incluidos en la URL
Abhi
fuente
1

Otra opción específica para este problema es un simple módulo contribuido con Drupal 8: Redirigir después de iniciar sesión . El módulo se puede encontrar aquí:

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

Como muestra la descripción, es un módulo simple y enfocado que está cubierto por la política de asesoramiento de seguridad de Drupal.

bkudrle
fuente
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
fuente