web-dev-qa-db-ja.com

ログアウト後にプログラムでリダイレクトを変更する

実際にDrupal 8で解決策を探しています。/user/logoutページにアクセスした後、リダイレクト先を変更します。ホームページの代わりに/ user/loginでユーザーをリダイレクトしたいのですが。

これを試してみてくださいが機能しません、私はまだホームページにリダイレクトしています:

/**
 * @file
 * Contains my_module.module.
 */

use Symfony\Component\HttpFoundation\RedirectResponse;

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

次の2つの理由により、コードは正しくありません。

  • RedirectResponse クラスにはsend()メソッドがありません。通常、そのクラスのオブジェクトが返されますが、 hook_user_logout() を呼び出す関数は、そのフックから返された値を使用しません。 (hook_user_logout()を呼び出すために使用されるコードを示す次のポイントを参照してください。)

  • コードが機能した場合、現在のユーザーのセッションが破棄される前にユーザーをリダイレクトします。つまり、現在ログインしているユーザーはログインしません。実際、hook_user_logout()を呼び出す関数( user_logout() )には次のコードが含まれています。

    _$user = \Drupal::currentUser();
    
    \Drupal::logger('user')->notice('Session closed for %name.', array('%name' => $user->getAccountName()));
    
    \Drupal::moduleHandler()->invokeAll('user_logout', array($user));
    
    // Destroy the current session, and reset $user to the anonymous user.
    // Note: In Symfony the session is intended to be destroyed with
    // Session::invalidate(). Regrettably this method is currently broken and may
    // lead to the creation of spurious session records in the database.
    // @see https://github.com/symfony/symfony/issues/12375
    \Drupal::service('session_manager')->destroy();
    $user->setAccount(new AnonymousUserSession());
    _

    hook_user_logout()が最初に呼び出され、その後、ログインしたユーザーのアカウントが匿名アカウントに置き換えられることは明らかです。 hook_user_logout()内でユーザーをリダイレクトする方法を見つけた場合、実際にはDrupalがユーザーのログアウトを停止することになります。

ユーザー/ログアウトルートのコントローラーは既にユーザーをフロントページにリダイレクトしているため、ユーザーをログインページにリダイレクトすることは私には役に立たないようです。

_public function logout() {
  user_logout();
  return $this->redirect('<front>');
}
_

ユーザーが再びログインできるようにする場合は、フロントページでログインブロックを表示するだけで十分です。

ユーザーがログアウト時にログインページにリダイレクトする必要がある場合は、ログアウトページのコントローラーを、ユーザーをログインページにリダイレクトする別のコントローラーに置き換える必要があります。

_class MyModuleUserController extends ControllerBase {

  /**
   * Constructs a MyModuleUserController object.
   *
   */
  public function __construct() {}

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static();
  }

  /**
   * Logs the current user out.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   A redirection to home page.
   */
  public function logout() {
    user_logout();
    return $this->redirect('user.logout');
  }

}
_

ControllerBase::redirect()には、URIではなくルート名が必要です。

既存のルートを変更する方法については、 既存のルートの変更と動的ルートに基づく新しいルートの追加 を参照してください。

4
kiamlaluno

hook_user_logout() はリダイレクト応答オブジェクトを想定しておらず、応答しません。

プログラムによるリダイレクトを強制する必要がない場合の1つの代替方法は、destinationクエリパラメータを使用することです。パラメータで指定されたパスは、ログアウト時にリダイレクトされます。例:http://example.com/user/logout?destination=user/loginはユーザーをログアウト後のログインページ。

3
Shawn Conn