ユーザーが特定の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を持っている人がいるかどうかです。別のものはどういうわけか私のものより優先されているのではないかと思い、その理論を確認または否定したいと思います。
上記のコード例では、イベントは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
イベントディスパッチャーサービスを使用して、特定のイベントのサブスクライバーのリストを優先度順にソートして取得できます。
$subscribers = \Drupal::service('event_dispatcher')
->getListeners(\Symfony\Component\HttpKernel\KernelEvents::REQUEST);