Je souhaite rediriger un utilisateur anonyme vers le formulaire de connexion si cet utilisateur rencontre une erreur 403.
J'ai créé un abonné aux événements et voici mon code, mais je me retrouve en boucle sur la page en cours.
/**
* Redirect anonymous user to login page if he encounters 404 or 403
* response.
*
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $response
* The created response object that will be returned.
* @param string $event
* The string representation of the event.
* @param \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $event_dispatcher
* Event dispatcher that lazily loads listeners and subscribers from the dependency injection
* container.
*/
public function checkLoginNeeded(GetResponseEvent $response, $event, ContainerAwareEventDispatcher $event_dispatcher) {
$routeMatch = RouteMatch::createFromRequest($response->getRequest());
$route_name = $routeMatch->getRouteName();
$is_anonymous = \Drupal::currentUser()->isAnonymous();
$is_not_login = $route_name != 'user.login';
if ($is_anonymous && $route_name == 'system.403' && $is_not_login) {
$query = $response->getRequest()->query->all();
// $query['destination'] = $routeMatch->getRouteObject()->getPath();
$query['destination'] = \Drupal::url('<current>');
$login_uri = \Drupal::url('user.login', [], ['query' => $query]);
$returnResponse = new RedirectResponse($login_uri, Response::HTTP_FOUND);
$response->setResponse($returnResponse);
}
}
Je pense que cela est lié au fait que la réponse contient déjà la destination (uri actuel) et system.404 et system.403 ont une haute priorité qui m'empêche de passer outre.
J'ai vu qu'il n'a jamais été répondu à cette question comment procéder par programme. Le code fonctionne réellement, lorsqu'il est placé dans un abonné d'exception:
/ src/EventSubscriber/RedirectOn403Subscriber.php:
<?php
namespace Drupal\mymodule\EventSubscriber;
use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
class RedirectOn403Subscriber extends HttpExceptionSubscriberBase {
protected $currentUser;
public function __construct(AccountInterface $current_user) {
$this->currentUser = $current_user;
}
protected function getHandledFormats() {
return ['html'];
}
public function on403(GetResponseForExceptionEvent $event) {
$request = $event->getRequest();
$is_anonymous = $this->currentUser->isAnonymous();
$route_name = $request->attributes->get('_route');
$is_not_login = $route_name != 'user.login';
if ($is_anonymous && $is_not_login) {
$query = $request->query->all();
$query['destination'] = Url::fromRoute('<current>')->toString();
$login_uri = Url::fromRoute('user.login', [], ['query' => $query])->toString();
$returnResponse = new RedirectResponse($login_uri);
$event->setResponse($returnResponse);
}
}
}
mymodule.services.yml:
services:
mymodule.exception403.subscriber:
class: Drupal\mymodule\EventSubscriber\RedirectOn403Subscriber
tags:
- { name: event_subscriber }
arguments: ['@current_user']
La façon la plus simple est de naviguer vers /admin/config/system/site-information
Et de remplir le champ qui lit Default 403 (access denied) page
avec user/login
En regardant simplement le titre de cette question (= Comment rediriger l'utilisateur vers le formulaire de connexion à partir de 403?), il y a 2 options pour le faire, sans aucun code personnalisé impliqué, comme détaillé ci-dessous.
Le module CustomError permet à l'administrateur du site de créer des pages d'erreur personnalisées pour les codes d'état HTTP 403 (accès refusé) et 404 (non trouvé), sans créer de nœuds pour chacun d'eux. Quelques détails supplémentaires sur ses fonctionnalités (depuis sa page de projet):
- Titre et descriptions des pages configurables.
- Il n'y a pas d'en-tête auteur et date/heure comme avec les nœuds normaux.
- Tout texte au format HTML peut être placé dans le corps de la page.
- Les pages d'erreur sont thématiques.
- Les utilisateurs qui ne sont pas connectés et tentent d'accéder à une zone nécessitant une connexion seront redirigés vers la page à laquelle ils tentaient d'accéder après leur connexion.
- Permet des redirections personnalisées pour 404s.
Vous serez probablement intéressé principalement par la partie sur " Les utilisateurs qui ne sont pas connectés et tentent d'accéder à une zone qui nécessite une connexion seront redirigés vers la page à laquelle ils tentaient d'accéder après leur connexion. = ".
Pour D8, il existe une version 8.x-1.x-dev pour ce module également disponible, plus de détails à ce sujet peuvent être trouvés dans Issue # 2219227 .
Supposons que le chemin de la page "403 par défaut" est défini sur no_access
(via admin). Créez ensuite une règle à l'aide du module Rules , avec comme Event quelque chose comme "Après avoir visité le nœud no_access
". Pour que l'ensemble de la règle ressemble à ceci:
no_access
Conditions:
Parameter: User: [site:current-user], Roles: anonymous user
Parameter: Text: [site:current-page:url], Matching text: user/login
Actions: Redirection de page - Parameter: URL: user/login
Si vous le souhaitez, vous pouvez même en ajouter un autre Action pour afficher également un message (informatif) dans la zone de message Drupal, avec quelque chose comme "Vous avez essayé de visitez une page pour laquelle une connexion est requise ... ".
Certes, cela peut vous obliger à activer un module supplémentaire contribué ( Rules ). Mais, comme l'indique également sa popularité croissante, ce module est probablement déjà activé dans la plupart des sites (similaire au module Views ), car il existe des dizaines de cas d'utilisation pour ce module.
Pour D8, il existe une version 8.x-3.x-alfa1 pour ce module également disponible, plus de détails sur sa version D8 peuvent être trouvés dans Issue # 2574691 , qui inclut un lien vers le problème des règles " Rules 8.x Roadmap "
Si ce qui précède ne vous aide pas, vous voudrez peut-être vérifier si la raison de votre boucle (ou "une priorité élevée" comme dans votre question) ne peut pas être empêchée/expliquée par quelque chose de similaire à la réponse à la question " Comment spécifier un événement Rules comme "Le contenu va" être "affiché"? ".
Je suppose que la solution à votre problème est simple. Vous pouvez facilement créer une page personnalisée pour 404
et 403
puis à l'intérieur de cette page, redirigez les utilisateurs anonymes vers le /user
page.
Vous pouvez utiliser ce code
function YOURTHEME_preprocess_page(&$vars) {
$header = drupal_get_http_header('status');
if ($header == '404 Not Found') {
$vars['theme_hook_suggestions'][] = 'page__404';
}
}
Chaque fois que 404 se produit, votre page--404.tpl.php
sera utilisé. Dans cette page, utilisez ce code
if(user_is_logged_in() == false){
/// You can do anything here.
}
Le Comment créer une page 403 et 404 personnalisée dans Drupal explique une autre méthode de création d'une page pour 403
et 404
.
La façon la plus simple de le faire est d'utiliser le module Redirect 403 to User Login (une version de développement de celui-ci existe pour D8). Voici une citation à ce sujet (à partir de sa page de projet):
Redirigez la page d'erreur HTTP 403 vers la page Drupal/user/login avec un message facultatif qui se lit comme suit:
"Accès refusé! Vous devez vous connecter pour voir cette page."
En outre, la page souhaitée est ajoutée dans la chaîne de requête URL de sorte que, une fois la connexion réussie, l'utilisateur est redirigé directement là où il essayait initialement d'aller.
(1) créer un nœud de page avec un alias comme "/my403.html"
(2) allez dans/admin/config/system/site-information et définissez "/my403.html" comme 403-Errorpage
(3) allez dans/admin/structure/block et ajoutez le bloc "User login" (Sec. Forms) à la zone de contenu principale. Limitez l'apparence du bloc à la page "my403.html" et au rôle "invité".
C'est ça.
Si vous avez besoin de plus de contrôle, créez un contrôleur pour votre page 403 et ajoutez manuellement UserLoginForm.
Cordialement, Rainer