เปลี่ยนเส้นทางหลังจากล็อกอินของผู้ใช้


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

4
ตามที่อธิบายโดย @kiamlaluno เราสามารถใช้$form_state->setRedirect('mymodule.dashboard);
Filipe Miguel Fonseca

3
โปรดอธิบายผู้ใช้ที่ปฏิบัติตามคำตอบนี้ mymodule.dashboard ควร / จะทำอย่างไร วิธีการเปลี่ยนเป็น <front> เพียงตัวอย่าง เนื่องจากแดชบอร์ดผู้ใช้เป็นการเปลี่ยนเส้นทางเริ่มต้นหลังจากเข้าสู่ระบบตัวอย่างนี้จึงไม่มีประโยชน์ ผู้ใช้ใหม่ไม่ทราบว่าส่วนใดบ้างที่ต้องแก้ไขและวิธีการเปลี่ยนเส้นทางของเขา
nilsun

1
ในการเปลี่ยนเส้นทางไปยังหน้าแรกคุณสามารถใช้ตัวอย่างด้านบน แต่เปลี่ยนบรรทัดที่สร้างออบเจ็กต์ $ url เป็น $ url = Url :: fromUri ('internal: /');
ตกลง

1
ฉันไม่เข้าใจว่าเกิดอะไรขึ้นที่elseนี่? รักษาการเปลี่ยนเส้นทางที่มีอยู่
user1359

1
คุณต้องใช้ใช้ 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;
}

นอกจากนี้คุณสามารถใช้โมดูลกฎแต่ยังไม่มีเวอร์ชั่นที่เสถียรสำหรับ Drupal 8


โซลูชันที่สง่างามที่ดีใช้ได้กับฉันใน Drupal 8.1
Alexei Rayu

3
ฉันได้รับERR_RESPONSE_HEADERS_MULTIPLE_LOCATIONข้อผิดพลาดในบางสถานการณ์ด้านบน - ฉันขอแนะนำให้แทนที่return;ด้วยexit;เพื่อให้แน่ใจว่าการเปลี่ยนเส้นทาง - ซึ่งกำหนดส่วนหัว - เป็นสิ่งสุดท้ายที่ต้องถูกประหารชีวิต

2
hook_user_login () ถูกเรียกใช้ก่อนตัวจัดการการส่งดังนั้นสิ่งนี้จะป้องกันไม่ให้ถูกเรียก คำตอบของ Yogesh ด้านล่างเป็นวิธีที่ดีกว่าในการทำสิ่งนี้
imclean

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 () ตามคำตอบอื่น ๆ อาจครอบคลุมกรณีการใช้งานของคนส่วนใหญ่และอาจเป็นคำตอบที่ 'ถูกต้อง' อย่างไรก็ตามการใช้ param แบบสอบถามปลายทางกับ hook_user_login หมายความว่าการส่งแบบฟอร์ม * ที่บันทึกในผู้ใช้จะเปลี่ยนเส้นทาง โดยไม่มีการรบกวนหรือความรู้ล่วงหน้าของส่วนอื่น ๆ ของแบบฟอร์ม / คำขอ

เช่นมันจะยังคงทำงานกับแบบฟอร์มการเข้าสู่ระบบที่กำหนดเองและการใช้ปลายทางไม่ได้หยุด hooks อื่น ๆ (มันถูกนำมาใช้โดย \Drupal\Core\EventSubscriber\RedirectResponseSubscriberในตอนท้ายของการประมวลผลการตอบสนอง)

* การส่งแบบฟอร์มใด ๆ ที่เรียกใช้ hook_user_login (user_login_finalize ()) และไม่ได้เรียก FormState :: setResponse ()ด้วยตนเอง


1
สิ่งนี้มีข้อดีของการทำงานหากการพิสูจน์ตัวตนเกิดขึ้นจากสิ่งอื่นที่ไม่ใช่แบบฟอร์มการเข้าสู่ระบบ แต่สิ่งนี้รบกวนการใช้งาน hook_user_login อื่น ๆ จากโมดูลอื่น ๆ หรือไม่?
Jonathan

1
@ โจนาธานไม่มันตั้งค่าเฉพาะปลายทางและไม่ได้ทำการร้องขอล่วงหน้า -> ส่ง () หรืออะไรก็ตาม (เช่น d7 drupal_goto) มันจะอนุญาตให้ hooks อื่น ๆ ทั้งหมดเรียกฟอร์มกลับมาทำงานเหมือนปกติก่อนที่จะดำเนินการตาม . นี่เป็นเพียงวิธีการที่มาตรฐานการเปลี่ยนเส้นทางการเข้าสู่ระบบ 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-overviewและapi.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/…
Sut3kh

2
นี่เป็นการแบ่งรหัสผ่านใหม่ดังนั้นฉันจึงลงคำตอบ (การสร้างตัวจัดการการส่งแบบฟอร์มสำหรับ user_login_form ตามที่แนะนำในคำตอบอื่น ๆ ใช้งานได้)
hansfn

7

คุณสามารถทำได้โดยใช้กฎ

ทำปฏิกิริยากับ: หลังจากที่ผู้ใช้เข้าสู่ระบบ

  • เพิ่มการกระทำ: เปลี่ยนเส้นทาง >> จากนั้นใช้พารามิเตอร์หรือพิมพ์ URL ของคุณ

3
ข้อแม้หลักเกี่ยวกับเรื่องนี้ก็คือกฎยังอยู่ในการเปิดตัว ALPHA สำหรับ Drupal 8 ดังนั้นโปรดดูแลหากคุณต้องการความเสถียรในเว็บไซต์ของคุณ
Philippe Gilbert

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 ()สำหรับรายละเอียดเพิ่มเติม


6

ใน D8 คุณสามารถใช้โมดูลหน้าเริ่มต้นของผู้ใช้เพื่อจุดประสงค์นี้

โมดูลนี้ช่วยให้คุณสามารถกำหนดปลายทางที่ผู้ใช้ถูกเปลี่ยนเส้นทางไปหลังจากเข้าสู่ระบบหรือออกจากระบบ คุณสามารถปรับแต่งตามบทบาทหรือผู้ใช้รายบุคคล


1
ใช้งานได้ แต่ไม่พิจารณาลิงค์รีเซ็ตรหัสผ่านเมื่อผู้ใช้ใช้ลิงค์ครั้งเดียวเพื่อตั้งรหัสผ่านผู้ใช้จะเปลี่ยนเส้นทางไปยังหน้าที่คุณตั้งค่าไว้ในโมดูลนี้ไม่ใช่บัญชีผู้ใช้
โซริน

1
โมดูลนี้ยังคงพักการรีเซ็ตรหัสผ่านดังนั้นฉันลงคำตอบ ดูdrupal.org/project/user_default_page/issues/2991916 (การสร้างตัวจัดการการส่งแบบฟอร์มสำหรับ user_login_form ตามที่แนะนำในคำตอบอื่นงาน.)
hansfn

4

มีโมดูลที่ง่ายต่อการทำเช่นนี้ซึ่งเข้ากันได้กับ Drupal 8. มันถูกเรียกว่าเป็นผู้ใช้เริ่มต้นหน้า

โมดูลช่วยให้คุณสามารถกำหนดปลายทางที่ผู้ใช้ถูกเปลี่ยนเส้นทางไปหลังจากเข้าสู่ระบบหรือออกจากระบบ คุณสามารถปรับแต่งตามบทบาทหรือผู้ใช้รายบุคคล และปรับแต่งข้อความ drupal ที่กำหนดค่าได้สำหรับการกระทำนี้


3

hook_user_login() ไม่ทำงานสำหรับการเปลี่ยนเส้นทางจะใช้หากคุณต้องการทำอะไรกับผู้ใช้เมื่อเขาเข้าสู่ระบบ Fx core แนะนำให้ผู้ใช้ตั้งเขตเวลาท้องถิ่นหากไม่ได้ตั้งค่าไว้

แต่คุณต้องใช้hook_form_alterในทุกรูปแบบการเข้าสู่ระบบและเพิ่มตัวจัดการการส่งแบบกำหนดเองซึ่งตั้งค่าการเปลี่ยนเส้นทางบนวัตถุสถานะแบบฟอร์ม


2

ฉันกำลังแสดงแบบฟอร์มการเข้าสู่ระบบในตัวควบคุมของฉันเอง วิธีนี้เป็นไปได้ที่จะจัดการกับแบบฟอร์ม (และเปลี่ยนเส้นทางผู้ใช้หลังจากเข้าสู่ระบบ) โดยไม่มี hooks ไม่ใช่ 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 และยังไม่มี Logintoboggan รุ่น Drupal 8
ตวัดเคลลี่แกง

1

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

  1. ติดตั้งโมดูลด้านบน
  2. เพิ่มเส้นทาง URL ที่กำหนดเองเป็นพารามิเตอร์ปลายทางใน URL
  3. ดังนั้นกำหนดค่าโมดูลข้างต้นเพื่อเปลี่ยนเส้นทางจาก

    / ผู้ใช้ / เข้าสู่ระบบ / ผู้ใช้ / เข้าสู่ระบบ? destination = 'CUSTOM_NODE_PATH'

    • ต้องการใช้โมดูลr4032loginเพื่ออนุญาตให้ผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์เข้าถึงหน้าเว็บที่เกี่ยวข้องเมื่อพวกเขาคัดลอก / วาง url หรือใช้ไฮเปอร์ลิงก์จาก word / excel เช่น
    • โมดูล 'การเปลี่ยนเส้นทางล็อกอิน' อื่น ๆ จะแทนที่ฟังก์ชันนี้และจะอนุญาตให้ผู้ใช้ลงจอดบนหน้าเดียวที่กำหนดค่าไว้แม้ว่าพารามิเตอร์ปลายทางจะรวมอยู่ใน URL

1

ตัวเลือกเฉพาะสำหรับปัญหานี้ก็คือโมดูลง่าย Drupal 8 ส่วนร่วม: เปลี่ยนเส้นทางหลังจากที่เข้าสู่ระบบ โมดูลสามารถพบได้ที่นี่:

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

ดังที่คำอธิบายแสดงให้เห็นว่าเป็นโมดูลที่เรียบง่ายและมุ่งเน้นที่ครอบคลุมโดยนโยบายการให้คำปรึกษาด้านความปลอดภัยของ Drupal


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 เวอร์ชั่นที่ใหม่กว่าโมดูลอื่น ๆ ที่นำเสนอโดยตรงบางตัวทำงานขาแบบที่ไม่มีความเกี่ยวข้องอีกต่อไปและ / หรือเพียงแค่ทรัพยากร hogging นอก ฉันได้รวบรวมตรรกะง่ายๆนี้ไว้ในโมดูลที่กำหนดเองสำหรับจัดการกระบวนการล็อกอิน:

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 ของฉันจากโมดูลอื่นที่ฉันสร้างขึ้นอีกครั้งได้อย่างถูกต้องสำหรับการสร้างบัญชีใหม่จากนั้นนำหน้าไปยังหน้าอื่นในการเข้าสู่ระบบไซต์ปกติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.