Redirect setelah pengguna masuk

14

Saya ingin mengarahkan pengguna setelah mereka masuk. Apakah mungkin digunakan hook_user_login()untuk melakukan pengalihan? Bagaimana cara menambahkan parameter untuk pengalihan?

John Chan
sumber

Jawaban:

19

Anda perlu mengubah formulir login dan menambahkan handler kirim yang akan menangani pengalihan. Anda tidak dapat menggunakan $form_state->setRedirectUrl()secara langsung dalam formulir alter, karena itu akan ditimpa oleh 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
sumber
4
Seperti yang dijelaskan oleh @kiamlaluno, orang juga dapat menggunakan$form_state->setRedirect('mymodule.dashboard);
Filipe Miguel Fonseca
3
Tolong jelaskan pengguna yang mengikuti jawaban ini apa yang harus / akan dilakukan mymodule.dashboard. Cara mengubahnya ke <front>, hanya sebagai contoh. Karena dasbor pengguna adalah pengalihan default setelah masuk, contoh ini di sini tidak berguna. Pengguna baru tidak tahu bagian mana yang harus diubah dan bagaimana pengalihannya.
nilsun
1
Untuk mengarahkan ulang ke halaman depan, Anda dapat menggunakan contoh di atas tetapi mengubah baris yang menghasilkan objek $ url menjadi $ url = Url :: fromUri ('internal: /');
oknate
1
Saya tidak mengerti apa yang terjadi di elsesini? Mempertahankan pengalihan yang ada?
user1359
1
Anda harus menggunakan Drupal \ Core \ Url; untuk membuatnya bekerja dengan benar
Jignesh Rawal
16

Mengarahkan pengguna setelah mereka masuk di situs Drupal 8 tidak berbeda dari yang dilakukan di Drupal 7, kecuali kode perlu disesuaikan untuk Drupal 8.

Khususnya:

  • hook_user_login()tidak digunakan untuk mengarahkan pengguna setelah mereka masuk, hanya karena fakta bahwa mengarahkan pengguna di kail itu akan menghentikan hook_user_login()implementasi lain dari dipanggil.
  • Cara yang benar untuk mengarahkan ulang pengguna adalah menambahkan penangan pengiriman formulir ke formulir login yang menggunakan kode yang mirip dengan yang berikut ini.

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

    Perhatikan bahwa user.page adalah nama perutean untuk jalur Drupal tempat Anda ingin pengguna diarahkan.
    Jika Anda memiliki instance Drupal\Core\Urlkelas, Anda juga bisa menggunakan kode berikut.

    $form_state->setRedirectUrl($url);

    Perlu diingat bahwa metode pertama lebih disukai ketika Anda mengarahkan pengguna ke halaman di situs yang sama dengan yang mereka masuki; metode kedua biasanya digunakan untuk mengarahkan ulang pengguna menggunakan URL eksternal.

kiamlaluno
sumber
11

Anda dapat menggunakan hook_user_login dan mencoba mengalihkan keyourpath

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

Anda juga dapat menggunakan modul Aturan , tetapi belum ada versi stabil untuk Drupal 8.

Yusef
sumber
Solusi elegan yang bagus, bekerja untuk saya di Drupal 8.1.
Alexei Rayu
3
Aku mulai ERR_RESPONSE_HEADERS_MULTIPLE_LOCATIONkesalahan dalam keadaan tertentu dengan di atas - saya sarankan mengganti return;dengan exit;, untuk memastikan redirect - yang set header - adalah hal terakhir yang akan dieksekusi.
2
hook_user_login () dipanggil sebelum submit handler jadi ini akan mencegah mereka dipanggil. Jawaban Yogesh di bawah adalah cara yang lebih baik untuk melakukan ini.
imclean
9

Agak terlambat ke pesta tetapi sesuai https://www.drupal.org/node/2068293#comment-11712455 Anda dapat mengatur tujuan di hook_user_login () untuk mengarahkan ulang di akhir pemrosesan login.

yaitu

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

Menggunakan FormState :: setRedirect () sesuai dengan jawaban lain mungkin akan mencakup sebagian besar kasus penggunaan orang dan berpotensi jawaban 'benar', namun menggunakan param kueri tujuan dengan hook_user_login berarti bahwa setiap bentuk pengiriman * yang dicatat oleh pengguna akan diarahkan tetapi tanpa gangguan atau pengetahuan sebelumnya tentang bagian lain dari formulir / permintaan.

yaitu masih akan bekerja dengan formulir login khusus dan menggunakan tujuan tidak menghentikan kait lain (ini diterapkan \Drupal\Core\EventSubscriber\RedirectResponseSubscriberpada akhir pemrosesan respons).

* Setiap formulir kirim yang memanggil hook_user_login (user_login_finalize ()) dan tidak secara manual memanggil FormState :: setResponse () .

Sut3kh
sumber
1
Ini memiliki keuntungan bekerja jika otentikasi terjadi dari sesuatu selain dari bentuk login. Tetapi apakah ini mengganggu implementasi hook_user_login lainnya dari modul lain?
Jonathan
1
@Jonathan Tidak, itu hanya menetapkan tujuan dan tidak melakukan permintaan awal-> kirim () atau apa pun (mis. Seperti d7 drupal_goto), itu akan memungkinkan semua kait lainnya, membentuk callback dll berjalan seperti biasa sebelum ditindaklanjuti . Ini hanya bagaimana pengalihan login drupal standar melakukannya.
Sut3kh
1
Tolong jelaskan pengguna yang mengikuti jawaban ini apa yang harus / akan dilakukan mymodule.dashboard. Cara mengubahnya ke <front>, hanya sebagai contoh. Karena dasbor pengguna adalah pengalihan default setelah masuk, contoh ini di sini tidak berguna. Pengguna baru tidak tahu bagian mana yang harus diubah dan bagaimana pengalihannya.
nilsun
3
@nilsun mymodule.dashboardadalah nama rute dan dapat diganti dengan nama rute apa pun (yaitu \Drupal\Core\Url::fromRoute('<front>')->toString()atau \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 123])->toString()). Untuk informasi lebih lanjut, lihat drupal.org/docs/8/api/routing-system/routing-system-overview dan api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/…
Sut3kh
2
Ini memecah pengaturan ulang kata sandi jadi saya memilih-bawah jawabannya. (Membuat handler pengajuan formulir untuk user_login_form seperti yang disarankan dalam karya jawaban lain.)
hansfn
7

Anda cukup melakukannya dengan menggunakan Aturan

Bereaksi pada: Setelah pengguna masuk

  • Tambahkan tindakan: Redirect >> lalu gunakan parameter atau ketik url Anda.
Nakal Shrikant
sumber
3
Peringatan utama dalam hal ini adalah bahwa Peraturan masih dalam pra-rilis ALPHA untuk Drupal 8 jadi berhati-hatilah jika Anda memerlukan stabilitas di situs web Anda
Philippe Gilbert
1
Aturan mengacaukan sistem login ketika situs telah diarahkan ke halaman setelah pengguna login. Hati
InspiredCoder
6

Anda juga dapat mengubah formulir login pengguna dan menambahkan handler ajukan kustom Anda sendiri untuk menetapkan $ form_state redirect, alih-alih secara langsung mengarahkan pengguna ke URL khusus Anda menggunakan 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');
}

Menambahkannya di $ form_state redirect akan memastikan bahwa pengirim lain / kait login dipanggil.

Seperti Drupal7, kami tidak dapat menetapkan $ form_state ['redirect'] secara langsung, karena $ form_state sekarang adalah objek kelas. Checkout FormState :: setRedirect () untuk detail lebih lanjut.

Yogesh
sumber
6

Di D8, Anda dapat menggunakan modul halaman default pengguna untuk tujuan ini.

Modul ini memungkinkan Anda untuk menyesuaikan tujuan yang diarahkan pengguna setelah masuk atau keluar. Anda dapat menyesuaikan berdasarkan peran atau pengguna individu.

Pallavi Chaudhury
sumber
1
Berfungsi tetapi tidak mempertimbangkan tautan pengaturan ulang kata sandi, saat pengguna menggunakan tautan satu kali untuk mengatur kata sandi, kata sandi akan mengarahkan ulang ke halaman yang Anda atur di modul ini dan bukan ke akun pengguna.
Sorin
1
Modul ini masih memecah pengaturan ulang kata sandi jadi saya memilih-bawah jawabannya. Lihat drupal.org/project/user_default_page/issues/2991916 (Membuat handler pengajuan formulir untuk user_login_form seperti yang disarankan dalam karya jawaban lain.)
hansfn
4

Ada modul sederhana untuk melakukan ini yang kompatibel dengan Drupal 8. Ini disebut User Default Page .

Modul ini memungkinkan Anda untuk menyesuaikan tujuan yang diarahkan pengguna setelah masuk atau keluar. Anda dapat menyesuaikan berdasarkan peran atau pengguna individu. Dan sesuaikan pesan drupal yang dapat dikonfigurasi untuk tindakan ini.

Pallavi Chaudhury
sumber
3

hook_user_login() tidak berfungsi untuk pengalihan, ini digunakan jika Anda ingin melakukan sesuatu dengan pengguna saat dia masuk. Fx core menyarankan pengguna untuk mengatur zona waktu lokal jika tidak diatur.

Alih-alih, Anda perlu menggunakan hook_form_altersemua formulir masuk dan menambahkan penangan kirim kustom yang menetapkan pengalihan pada objek status formulir.

googletorp
sumber
2

Saya menampilkan formulir login di controller saya sendiri. Dengan cara itu dimungkinkan untuk memanipulasi formulir (dan mengarahkan pengguna setelah masuk) tanpa kait non-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;

Ubah rute 'proreos.home' ke tujuan apa pun yang Anda butuhkan.

Salam

Rainer

Rainer Feike
sumber
2

Saya menggunakan cuplikan berikut cukup banyak sehingga saya pikir saya akan membagikannya. Anda dapat menambahkan arahan yang berbeda tergantung pada peran yang dimiliki pengguna.

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

Anda dapat menggunakan modul logintoboggan untuk pengalihan. Ini memiliki konfigurasi lain yang mungkin berguna jika Anda ingin functionlaities lain seperti login menggunakan nama pengguna.

nitvirus
sumber
2
Jawaban yang bagus untuk D7, tetapi pertanyaan ini ditandai D8, dan belum ada versi Drupal 8 dari Logintoboggan.
Kelley Curry
1

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

  1. Pasang modul di atas
  2. Tambahkan jalur url khusus sebagai parameter tujuan di url
  3. Jadi, konfigurasikan modul di atas untuk mengalihkan dari

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

    • Ingin menggunakan modul r4032login untuk memungkinkan pengguna terotentikasi mengakses halaman yang bersangkutan, ketika mereka menyalin / menempelkan url atau menggunakan hyperlink dari kata / excel misalnya.
    • Modul 'login redirect' lainnya akan menimpa fungsi ini dan hanya akan memungkinkan pengguna untuk mendarat di halaman tunggal yang dikonfigurasikan bahkan ketika parameter tujuan dimasukkan dalam url
Abhi
sumber
1

Opsi lain yang khusus untuk masalah ini adalah modul sederhana kontribusi Drupal 8: Pengalihan Setelah Masuk . Modul ini dapat ditemukan di sini:

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

Seperti yang diperlihatkan oleh deskripsi, ini adalah modul sederhana, terfokus yang dicakup oleh kebijakan penasihat keamanan Drupal.

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