Last active
April 2, 2023 19:16
Drupal 8 | Redirect all anonymous users to login page. With a few needed exceptions like /user/password
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 with latest version of Drupal, try to replace these lines:
$event->setResponse($response);
$event->stopPropagation();
with:
$response->send();
this worked for me:
$response = new RedirectResponse($base_url . '/user/login', 302);
// $event->setResponse($response);
// $event->stopPropagation();
// return;
$response->send();
This module also does the job: https://www.drupal.org/project/anonymous_login
This really helpful. Initially It went into error "redirecting too many times" but with @gzveri comment it got solved. Thanks.
$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;
}
}
I've tried all the solutions and still got endless redirection
@mogbril
i think you may have other redirection in your .htaccess or somewhere else that is creating loop
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
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.