ユーザーがログインしたときに、特定の役割を持つユーザーを別のページにリダイレクトしたい。 Drupal 7では、drupal_goto()
でhook_user_login()
を使用してリダイレクトを行い、hook_module_implements_alter()
を使用してモジュールはリストの最後にあるため、他のすべてが実行される可能性があります。
Drupal 8では、コントローラーの外部でリダイレクトを実行することは、サポートされているユースケースではないようです。
そのページでは、gngnにも同じ問題があり、RedirectResponseを手動で生成して送信します。
問題は、私が見ると、send()
はリクエストを終了せず、ページには2つのHTMLドキュメントがあることです。「リダイレクト先...」ページの後に、そこにあったページが続きます。そもそも。これはセキュリティ上の問題になる可能性があります。
johnvbはこれに注意し、exit()
の後にsend()
への呼び出しを挿入します。
おそらく何か便利なことがindex.phpの$kernel->terminate()
呼び出しで行われており、exit()
を呼び出すことでバイパスされています。
Drupal 7では、drupal_goto()
がdrupal_exit()
を呼び出してこの問題を処理しました。
drupal_goto()
が削除されました は、リクエストフローを中断する必要があるモジュールがHTTP例外をスローする必要があることを示していますが、「リダイレクト」例外はありません。
ユーザーログインもリダイレクトを行うため、上記のdrupal_goto()
変更レコードリンクで提案されているように、リダイレクトURLを変更する方法もあります。ただし、そのアプローチでは、すべてのリクエストで私のメソッドが呼び出されることになり、私がやっていることはめちゃくちゃ無駄に見えます。
Drupal 8)でhook_form_alter()
からリダイレクトを実行するにはどうすればよいですか?
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_form_FORM_ID_alter().
*/
function [MODULENAME]_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Alter login form and add own custom submit handler.
$form['#submit'][] = '_[MODULENAME]_user_login_form_submit';
// Not all forms pay attention to $form['#submit'][]. For these
// try adding your submit hook to the #submit for the specific
// button. e.g.,
$form['actions']['submit']['#submit'][] = '_[MODULENAME]_user_login_form_submit';
}
/**
* Custom submit handler for login form.
*/
function _[MODULENAME]_user_login_form_submit($form, FormStateInterface $form_state) {
// Set redirect to login form.
$form_state->setRedirect('custom.redirect_callback');
}
ログイン後にユーザーをリダイレクトする方法はいくつかあります。前の回答と同様に、hook_form_FORM_ID_alter()を実装して追加の送信関数を追加することで実行できますが、hook_user_login関数も使用できます。
いくつかのURLを生成するパラメーターを持ついくつかのルートにリダイレクトするには(Symfony\Component\Validator\Constraints\Url class reference を使用):
$form_state->setRedirectUrl(new Url('route_name', ['route' => 'parameters']));
あるルートにリダイレクトするには:
$form_state->setRedirect('route_name', ['route' => 'parameters']);
また、Symfony\Component\HttpFoundation\RedirectResponse
、たとえば、ユーザーをカスタムユーザーページにリダイレクトする場合:
function your_module_user_login($account) {
global $base_url;
$redirect = new RedirectResponse($base_url .'/your-url/'.$account->uid->value);
$redirect->send();
}
Drupal 8)で、フォームの送信後にリダイレクトを設定する正しい方法は、次の手順に従います。
hook_form_alter()
または hook_form_FORM_ID_alter()
を実装して、フォーム送信ハンドラをフォームに追加しますFormState::setRedirect()
を使用するか、または FormState::setRedirectUrl()
、これは引数として _\Drupal\Core\Url
_ オブジェクトを必要とします。別の方法としては、redirect.destinationサービスを使用します。この場合、Drupal 8でも、hook_user_login()
を使用できます。
_function mymodule_user_login(UserInterface $account) {
\Drupal::destination()->set($url_destination_as_string);
}
_
RedirectDestination::set()
のドキュメントには、次のように書かれています:
すべてのレンダリングですべての宛先呼び出しをオーバーライドするために、このメソッドが使用されることはめったにありません。たとえば、ビューはこのメソッドを使用します。
補足として、ログイン後にユーザーをリダイレクトする正しい方法は、Drupal 7で)、次のようなコードを使用しています。
_function mymodule_user_login(&$edit, $account) {
$edit['redirect'] = $path_to_redirect_users_to;
}
_
これは、フックが受け取る_&$edit
_パラメーターが、ログインフォーム送信ハンドラーに渡される_$form_state
_パラメーターであるため機能します。
_function user_login_submit($form, &$form_state) {
global $user;
$user = user_load($form_state['uid']);
$form_state['redirect'] = 'user/' . $user->uid;
user_login_finalize($form_state);
}
function user_login_finalize(&$edit = array()) {
global $user;
watchdog('user', 'Session opened for %name.', array(
'%name' => $user->name,
));
// Update the user table timestamp noting user has logged in.
// This is also used to invalidate one-time login links.
$user->login = REQUEST_TIME;
db_update('users')
->fields(array(
'login' => $user->login,
))
->condition('uid', $user->uid)
->execute();
// Regenerate the session ID to prevent against session fixation attacks.
// This is called before hook_user in case one of those functions fails
// or incorrectly does a redirect which would leave the old session in place.
drupal_session_regenerate();
user_module_invoke('login', $edit, $user);
}
_