0

I'm working on a module that shows a different frontpage per role. I have three frontpages:

  1. the base www.domain.nl for anonymous users, set in the basic site settings
  2. for users with role_1 they go to sub1.domain.nl\dashboard
  3. for users with role_2 they go to sub2.domain.nl\dashboard

I'm almost there but the frontpage url is set in cache (I think) therefor when I login I get the right frontpage. So I have role_1 en go to sub1.domain.nl. Now when I logout I want to go back to www.domain.nl but I still get redirected to sub1.domain.nl. Even when I close the browser and return to the site I still get back to sub1.domain.nl.

So my question is how can I make sure this response is cleared from cache after loggin out or is not even cached at all? What is the best method to deal with this?

My code till now:

mymodule.services.yml

services:
  mymodule.event_subscriber:
    class: Drupal\mymodule\EventSubscriber\FrontpageSubscriber
    tags:
      - {name: event_subscriber}

src/EventSubscriber/FrontpageSubscriber.php

<?php

namespace Drupal\mymodule\EventSubscriber;

use Drupal\Core\Routing\TrustedRedirectResponse;

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

class FrontpageSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  public function checkFrontRedirection(GetResponseEvent $event) {
    $current_path = \Drupal::service('path.current')->getPath();
    $front_uri = \Drupal::config('system.site')->get('page.front');
    $front_alias = \Drupal::service('path.alias_manager')->getAliasByPath($front_uri);
    $current_alias = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);
    $isFrontPage = \Drupal::service('path.matcher')->isFrontPage() || $front_alias === $current_alias;

    if ($isFrontPage) {
      $hasRole1 = \Drupal\user\Entity\User::load(\Drupal::currentUser()
        ->id())->hasRole('role_1');
      $hasRole2 = \Drupal\user\Entity\User::load(\Drupal::currentUser()
        ->id())->hasRole('role_2');

        if ($hasRole1) {
          $domain_url = 'https://sub1.domain.nl/dashboard';
          $response = new TrustedRedirectResponse($domain_url);
          $event->setResponse($response);
        }

        if ($hasRole2) {
          $domain_url = 'https://sub2.domain.nl/dashboard';
          $response = new TrustedRedirectResponse($domain_url);
          $event->setResponse($response);
        }
     }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('checkFrontRedirection');
    return $events;
  }
}
4

Could be a caching issue within the browser, Drupal or both. For the browser set cache headers in the response, see https://drupal.stackexchange.com/a/278703/47547.

For Drupal caching add a cache context user.roles:

$response->getCacheableMetadata()->addCacheContexts(['user.roles']);

Furthermore it is recommended to execute a redirect event subscriber only on a master request, this helps to prevent redirect loops:

public function checkFrontRedirection(RequestEvent $event) {
  if (!$event->isMainRequest()) {
    return;
  }
  ...
}

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.