web-dev-qa-db-ja.com

登録されているすべてのイベントを表示しますか?

ユーザーが特定のURL(www.mysite.com/special-content)リクエストに宛先を追加したログインページにリダイレクトされます(www.mysite.com/user/login?destination=special-content)。

checkAuthStatusイベントサブスクライバーを使用してカスタムモジュールを作成し、匿名ユーザーを検出して適切にリダイレクトしました。

$ cat src/EventSubscriber/RedirectAnonymousSubscriber.php
<?php

namespace Drupal\anon_redirect\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) {
    $paths = [
      '/special-content',
      '/more-special-content'
    ];

    if ($this->account->isAnonymous()) {
      foreach ( $paths as $path ) {
        if ( substr($_SERVER['REQUEST_URI'], 0, strlen($path)) === $path ) {
          $url = \Drupal\Core\Url::fromUri('internal:/user/login',[
            'query'=>['destination'=>$_SERVER['REQUEST_URI']],
          ]);
          $response = new RedirectResponse('/user/login?destination='.$_SERVER['REQUEST_URI'], 302);
          $response->send();
          return;
        }
      }
    }

  }

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

これは数か月間は問題なく機能していましたが、最近、リダイレクトされないという不満が出てきました。調査の結果、ウォッチドッグログで証明されているように、「アクセスが拒否された」ことがわかりました。つまり、ログインしていない場合、リダイレクトされるのではなく、301ページが表示されます。

イライラして、私はこの問題を断続的に再現することしかできませんでした。時々私は301ページを取得し、時には適切なリダイレクトクエリが追加されたログインページを取得します。私はFirefoxとChromeの両方、プライベートセッション、Cookieのクリアなどを試しました。

私は、アクセスを決定するものは何でもcheckAuthStatus時々を聞いていると思います。最終的にどのページがエンドユーザーに送信されるかについての最終的なWordがあり、モジュールの動作は実装されていません。それ以外の場合は、イベントリスナーが呼び出されます。

私の質問は、どのイベントリスナーがcheckAuthStatusイベントにサブスクライブされているかを確認する方法があるかどうか、そして理想的には、Drupalからの最終的な応答に関して最終的なWordを持っている人がいるかどうかです。別のものはどういうわけか私のものより優先されているのではないかと思い、その理論を確認または否定したいと思います。

1
user1359

上記のコード例では、イベントはKernelEvents::RequestおよびcheckAuthStatusは、Requestイベントが送出されたときに呼び出されるメソッドです。

Drupal Console debug:eventコマンドを使用して、特定のイベントのすべてのサブスクライバーをリストします。

vendor/bin/drupal debug:event kernel.request

そしてそれはあなたに次のようなものを与えます:

  Drupal\Core\EventSubscriber\OptionsRequestSubscriber                   onRequest: 1000
  Drupal\Core\EventSubscriber\RedirectLeadingSlashesSubscriber           redirect: 1000
  Drupal\Core\EventSubscriber\AuthenticationSubscriber                   onKernelRequestAuthenticate: 300
  Drupal\language\EventSubscriber\LanguageRequestSubscriber              onKernelRequestLanguage: 255
  Drupal\Core\EventSubscriber\RedirectResponseSubscriber                 sanitizeDestination: 100
  Drupal\Core\EventSubscriber\AjaxResponseSubscriber                     onRequest: 50
  Symfony\Component\HttpKernel\EventListener\RouterListener              onKernelRequest: 32
  Drupal\Core\EventSubscriber\AuthenticationSubscriber                   onKernelRequestFilterProvider: 31
  Drupal\user\EventSubscriber\MaintenanceModeSubscriber                  onKernelRequestMaintenance: 31
  Drupal\Core\EventSubscriber\MaintenanceModeSubscriber                  onKernelRequestMaintenance: 30
  Drupal\Core\Routing\RoutePreloader                                     onRequest: 0
  Drupal\Core\EventSubscriber\ReplicaDatabaseIgnoreSubscriber            checkReplicaServer: 0

Drushを使用していて、develモジュールがインストールされている場合は、次のことができます。

vendor/bin/drush devel-event kernel.request
2
johndevman

イベントディスパッチャーサービスを使用して、特定のイベントのサブスクライバーのリストを優先度順にソートして取得できます。

$subscribers = \Drupal::service('event_dispatcher')
  ->getListeners(\Symfony\Component\HttpKernel\KernelEvents::REQUEST);
0
Clive