3

I'm actually looking for a solution in Drupal 8 to change the redirection destination after visiting /user/logout page. I want to redirect the user on /user/login instead of home page.

Try this but not working, I'm still redirect on home page :

/**
 * @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;
}
5

The code is not correct for two reasons:

  • The RedirectResponse class doesn't have a send() method. An object of that class is normally returned, but the function invoking hook_user_logout() doesn't use the value returned from that hook. (See the next point, which shows the code used to invoke hook_user_logout().)

  • In the case the code worked, it would redirect the user before the session for the current user is destroyed, which means the the currently logged-in user would not be logged in. In fact, the function invoking hook_user_logout() (user_logout()) contains the following code.

    $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());
    

    It's clear that hook_user_logout() is first invoked, and then the account for the logged-in user is replaced with the anonymous account. If you were to find a way to redirect the users inside hook_user_logout(), you would be actually stopping Drupal from logging out the users.

Redirecting the users to the login page seems useless to me, since the controller for user/logout route already redirects the users to the front page.

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

If you want to allow the users to login again, it is sufficient to make the login block visible on the front page.

If you really needed to redirect the users to the login page when they log out, you should replace the controller for the logout page with a different one that redirect users to the login page.

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

}

Notice that ControllerBase::redirect() requires a route name, not a URI.

For how to alter an existing route, see Altering existing routes and adding new routes based on dynamic ones.

5

hook_user_logout() doesn't expect a redirect response object and won't respond to it.

One alternative here, if you don't need a programmatic forcing of redirection, is to use the destination query parameter. The path supplied in the parameter will be redirected to upon logout. For example: http://example.com/user/logout?destination=user/login will return a user to the login page following logout.

2
1
namespace Drupal\module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\RedirectResponse;

class ModuleLogoutController extends ControllerBase {

  public function logout($dest) 
  {
    global $base_url;

    \Drupal::service('session_manager')->destroy();

    $response = new RedirectResponse($base_url . '/' . $dest);
    $response->send();
  
    return;
  }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.