Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Drupal 8 | Redirect all anonymous users to login page. With a few needed exceptions like /user/password
<?php
namespace Drupal\<yourmodulename>\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Event subscriber subscribing to KernelEvents::REQUEST.
*/
class RedirectAnonymousSubscriber implements EventSubscriberInterface {
public function checkAuthStatus(GetResponseEvent $event) {
global $base_url;
if (
\Drupal::currentUser()->isAnonymous() &&
\Drupal::routeMatch()->getRouteName() != 'user.login' &&
\Drupal::routeMatch()->getRouteName() != 'user.reset' &&
\Drupal::routeMatch()->getRouteName() != 'user.reset.form' &&
\Drupal::routeMatch()->getRouteName() != 'user.reset.login' &&
\Drupal::routeMatch()->getRouteName() != 'user.pass' ) {
// add logic to check other routes you want available to anonymous users,
// otherwise, redirect to login page.
$route_name = \Drupal::routeMatch()->getRouteName();
if (strpos($route_name, 'view') === 0 && strpos($route_name, 'rest_') !== FALSE) {
return;
}
$response = new RedirectResponse($base_url . '/user/login', 301);
$event->setResponse($response);
$event->stopPropagation();
return;
}
}
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('checkAuthStatus');
return $events;
}
}
@ashish-cummins

This comment has been minimized.

Copy link

@ashish-cummins ashish-cummins commented Aug 9, 2018

hello,

This is really helpful understand Event Subscriber. I am also trying to redirect anonymous user to login page with your code. but it is not working for me, it is giving me "Redirecting too many times..." error. Can you please help why this is happening and what is the solution over it. Thanks in advance.

@ashish-cummins

This comment has been minimized.

Copy link

@ashish-cummins ashish-cummins commented Aug 9, 2018

capture

@yommu

This comment has been minimized.

Copy link

@yommu yommu commented Sep 18, 2018

@ashish-cummins with latest version of Drupal, try to replace these lines:

$event->setResponse($response);
$event->stopPropagation();

with:

$response->send();
@gzveri

This comment has been minimized.

Copy link

@gzveri gzveri commented Apr 4, 2019

this worked for me:

      $response = new RedirectResponse($base_url . '/user/login', 302);
//      $event->setResponse($response);
//      $event->stopPropagation();
//      return;
      $response->send();

@jorislucius

This comment has been minimized.

Copy link
Owner Author

@jorislucius jorislucius commented Jul 17, 2019

This module also does the job: https://www.drupal.org/project/anonymous_login

@saadwaseem

This comment has been minimized.

Copy link

@saadwaseem saadwaseem commented Sep 8, 2020

This really helpful. Initially It went into error "redirecting too many times" but with @gzveri comment it got solved. Thanks.

@flyke

This comment has been minimized.

Copy link

@flyke flyke commented Oct 8, 2020

$response->send(); works for me too, thanks!

namespace Drupal\starterkit_helper\EventSubscriber;

use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Event subscriber subscribing to KernelEvents::REQUEST.
 */
class RedirectAnonymousSubscriber implements EventSubscriberInterface {

  /**
   *
   */
  public function checkAuthStatus(GetResponseEvent $event) {

    $loginUrl = Url::fromRoute('user.login')->toString();
    $routeName = \Drupal::routeMatch()->getRouteName();

    if (
        \Drupal::currentUser()->isAnonymous() &&
        $routeName != 'user.login' &&
        $routeName != 'user.reset' &&
        $routeName != 'user.reset.form' &&
        $routeName != 'user.reset.login' &&
        $routeName != 'user.pass') {
      // Add logic to check other routes you want available to anonymous users,
      // otherwise, redirect to login page.
      if (strpos($routeName, 'view') === 0 && strpos($routeName, 'rest_') !== FALSE) {
        return;
      }

      $response = new RedirectResponse($loginUrl, 301);
      $response->send();
    }
  }

  /**
   *
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ['checkAuthStatus'];
    return $events;
  }

}

@mogbril

This comment has been minimized.

Copy link

@mogbril mogbril commented Feb 26, 2021

I've tried all the solutions and still got endless redirection

@rkhregar

This comment has been minimized.

Copy link

@rkhregar rkhregar commented Mar 4, 2021

@mogbril
i think you may have other redirection in your .htaccess or somewhere else that is creating loop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment