Skip to content

Instantly share code, notes, and snippets.

@jorislucius
Last active April 2, 2023 19:16
Show Gist options
  • Select an option

  • Save jorislucius/8c524fb45e8a25657d474c0abe9ef48f to your computer and use it in GitHub Desktop.

Select an option

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;
}
}
@ashish-cummins

Copy link
Copy Markdown

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

Copy link
Copy Markdown

capture

@yommu

yommu commented Sep 18, 2018

Copy link
Copy Markdown

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

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

with:

$response->send();

@gzveri

gzveri commented Apr 4, 2019

Copy link
Copy Markdown

this worked for me:

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

@jorislucius

Copy link
Copy Markdown
Author

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

@saadwaseem

Copy link
Copy Markdown

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

@flyke

flyke commented Oct 8, 2020

Copy link
Copy Markdown

$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

mogbril commented Feb 26, 2021

Copy link
Copy Markdown

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

@rkhregar

rkhregar commented Mar 4, 2021

Copy link
Copy Markdown

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

@lonalore

lonalore commented Apr 2, 2023

Copy link
Copy Markdown

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