Skip to content

Instantly share code, notes, and snippets.

@jorislucius
Last active April 2, 2023 19:16
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jorislucius/8c524fb45e8a25657d474c0abe9ef48f to your computer and use it in GitHub Desktop.
Save jorislucius/8c524fb45e8a25657d474c0abe9ef48f to your computer and use it in GitHub Desktop.
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;
}
}
@gzveri
Copy link

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
Copy link
Author

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

@saadwaseem
Copy link

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

@flyke
Copy link

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
Copy link

mogbril commented Feb 26, 2021

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

@rkhregar
Copy link

rkhregar commented Mar 4, 2021

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

@lonalore
Copy link

lonalore commented Apr 2, 2023

My solution under Drupal v9.5.7:

<?php

namespace Drupal\[MODULE]\EventSubscriber;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Class EventSubscriber.
 */
class EventSubscriber implements EventSubscriberInterface {

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $account;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user.
   */
  public function __construct(AccountInterface $account) {
    $this->account = $account;
  }

  /**
   * Redirects users when access is denied.
   *
   * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
   *   The event to process.
   */
  public function onException(ExceptionEvent $event) {
    $exception = $event->getThrowable();
    if ($exception instanceof HttpExceptionInterface && $exception->getStatusCode() === 403) {
      if (!$this->account->isAuthenticated()) {
        $url = Url::fromRoute('user.register');
        $response = new RedirectResponse($url->toString());
        $event->setResponse($response);
      }
    }
  }

  /**
   * Events.
   */
  public static function getSubscribedEvents(): array {
    return [
      KernelEvents::EXCEPTION                => [
        ['onException', 80],
      ],
    ];
  }

}

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