12

I want if user not logged in and visit any page of my website except my REST VIEWS routers I redirect him/her to login page in drupal 8, I found this solutions for drupal 7 but didn't find any solution for Drupal 8,

  • 2
    In code you would write an event subscriber to act on KernelEvents::REQUEST event and then set the response to a RedirectResponse for the login page. – mradcliffe Dec 15 '16 at 21:47
  • 1
    I thought of something else. You could set the 403 page to /user and then if they're anonymous, it would take them to /user/login, but with the side effect of taking authenticated users to their user profile without telling them they've been denied access to the page they were looking for. – mradcliffe Dec 15 '16 at 22:54
  • Use the following module to add a login redirect for anonymous users, it has a setting to exclude paths so I think you can add your rest paths in that. drupal.org/project/anonymous_redirect – Daniel Harper Mar 22 '18 at 10:49
  • This module also does the job: drupal.org/project/anonymous_login – Joris Lucius Jul 17 at 14:22
18

You can test a user's status very early with event subscriber in a custom module that subscribes to KernelEvents::REQUEST.

First, you register the event subscriber in mymodule.services.yml in your module folder:

services:
  mymodule.event_subscriber:
    class: Drupal\mymodule\EventSubscriber\RedirectAnonymousSubscriber
    arguments: []
    tags:
      - {name: event_subscriber}

Then add RedirectAnonymousSubscriber.php for your custom event subscriber in your module in the /src/EventSubscriber/ folder.

namespace Drupal\mymodule\EventSubscriber;

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

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

  public function __construct() {
    $this->account = \Drupal::currentUser();
  }

  public function checkAuthStatus(GetResponseEvent $event) {

    if ($this->account->isAnonymous() && \Drupal::routeMatch()->getRouteName() != 'user.login') {

      // 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('/user/login', 301);
      $event->setResponse($response);
      $event->stopPropagation();
    }
  }

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

}
  • thanks to @mradcliffe for the idea for the event subscriber – oknate Dec 15 '16 at 23:03
  • 1
    he should create RedirectAnonymousSubscriber.php ,I update your answer. – Yusef Mohamadi Dec 16 '16 at 8:28
  • @oknate what if user is on /registration or /forget-password or /logout route ? Shouldn't it check for those routes as well in the if condition ? As as per this, the user might be redirect while registering or request for the new password. – Juyal Jee Jul 17 at 6:48
5

First, create a service for your event subscriber in module-name.services.yml

Code -

services:
    [MODULE-NAME]_event_subscriber:
        class: Drupal\MODULE-NAME\EventSubscriber\[Event-Subscriber-class]
        tags:
        - {name: event_subscriber}

Create your own eventsubscriber class inside modules/module-name/src/EventSubscriber directory:

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

class Event-Subscriber-class implements EventSubscriberInterface {

  private $redirectCode = 301;

  public function checkForRedirection2(GetResponseEvent $event) {
    $account = \Drupal::currentUser(); 
    if (empty($account->id()) {
      $response = new RedirectResponse('/', $this->redirectCode);
      $response->send();
      exit(0);
    }
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('checkForRedirection2');
    return $events;
  }
}
4

On Drupal 8.3.3, this code causes an endless redirection. I've fixed that by adding that instead.

..
$response = new RedirectResponse('/user/login', 301);
$response->send();
..

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.