Symfony, Vue, et 403

Le problème exposé dans ce sujet a été résolu.

Bonjour,

J’ai eu l’idée bancale il y a quelques mois de me lancer dans un projet énorme utilisant d’un côté Symfony pour gérer le back-end (données via API Platform, sécurité via Guard, Symfony Voters etc.) et d’un autre côté Vue pour un Front-end moderne et efficace. Sur l’essentiel maintenant, ça fonctionne.

Parmi les problèmes qui me restent à régler, il y a le cas de la redirection en cas d’erreur d’authentification. En gros, j’ai deux espaces sur l’application : une zone publique à la racine avec une demi-douzaine de pages publiques, et une zone privée où il faut avoir le ROLE_ADMIN de Symfony pour pénétrer. Cette sécurité est notamment définie dans le fichier security.yaml, section access_control. C’est une configuration tout à fait classique. Ces deux zones sont deux points d’accès différents définis dans le fichier webpack.config.js.

Ce qui se passe, c’est que si je rentre l’adresse "localhost:8000/admin" et que je ne suis pas identifié avant, j’ai une page blanche ; dans la console quand je charge la page, j’ai une erreur 403 sur "GET [blabla]/admin", ce qui est tout à fait normal, on est bien d’accord. Ce que je veux, c’est justement rediriger vers l’accueil du site, et je ne sais pas comment faire ça.

Ce que j’ai essayé du côte Symfony :

main:
  entry_point: App\Security\AuthenticationEntryPoint
  access_denied_handler: App\Security\AccessDeniedHandler  

  anonymous: true           

  json_login:
      check_path: app_login
      username_path: email
      password_path: password                         

  logout:
      path: app_logout

J’ai défini les entry_point et access_denied_handler tirés de cette page. Même un "dd($request)" n’apparait pas.

Côté Vue, j’ai mis en place un "hook beforeeach" sur le Routeur.

router.beforeEach(async (to, from, next) => {
  console.log('bouh')
  const { requiresAuth } = to.meta;
  if (requiresAuth) {
    try {
      await axios.get('/api/adminCheck')
        .then(resp => {
          console.log(resp.data);
        });
      next();
    } catch (e) {
      next('/error')
    }
  }
})

Le 'bouh' qui est censé apparaitre à chaque changement de page n’apparait que si on est identifié. Cela ne se déclenche pas sinon, ce qui me fait penser que tout le problème vient de Symfony, qui intercepte l’erreur avant que Vue ne se lance.

Quelqu’un saurait-il me conseiller pour avancer sur ce problème ? Comment réussir à localiser le moment où la redirection vers une erreur 403 ne se fait pas ? Comment savoir si le access_denied_handler défini dans security.yaml peut fonctionner ? A ce stade, même une page moche Symfony 403 me ferait plaisir à voir.

Merci.

+0 -0

Ce qui se passe, c’est que si je rentre l’adresse "localhost:8000/admin" et que je ne suis pas identifié avant, j’ai une page blanche ; dans la console quand je charge la page, j’ai une erreur 403 sur "GET [blabla]/admin", ce qui est tout à fait normal, on est bien d’accord. Ce que je veux, c’est justement rediriger vers l’accueil du site, et je ne sais pas comment faire ça.

JeanTilapin

C’est ça ton problème principal ?

Alors, quand tu tapes, localhost:8080/admin. Tu reçois une erreur 403, tu n’as pas VueJS de chargé. VueJS est chargé sur une page normal qui l’inclue. Une erreur 403 n’inclue généralement pas de page avec, est-ce le cas ici ? Retourne tu une pages avec l’erreur 403 ?

D’ailleurs, je pense que tu devrais retournée une erreur 401 et pas 403.

Peut-être devrait tu tous simplement retourner une page avec une redirection HTML.

+0 -0

Sans vouloir dire d’âneries (je peux pas vérifier là dans l’instant) : Symfony balance théoriquement une page d’erreur en mode développement pour l’erreur 403, non ? Avec le template qui détaille tout le fil requête -> réponse et là où ça a raté ? Parce que là je n’ai qu’une page blanche, alors que si je cherche à obtenir une 404, j’ai bien la page d’erreur, pareil pour la 500. Mais rien pour 403.

(Soit dit en passant, je perçois mal la différence entre 401 et 403)

Ce n’est pas moi qui choisis ce qui est retourné, c’est manifestement Symfony. C’est tout le but de ce que j’ai essayé de faire avec le entry_point et le access_denied_handler du fichier Security. Quel test simple pourrais-je effectuer pour voir si ils sont pris en compte d’une manière ou d’une autre ? A priori, un simple dd(’bouh’) ne suffit pas.

class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
    public function handle(Request $request, AccessDeniedException $accessDeniedException): ?Response
    {
        dd('bouh');        
    }
}

N’ayant pour l’instant aucun contrôle sur ce qui est retourné, je ne peux pas tester la page avec la redirection html que tu suggères.

Un test simple ? 🤔

Quand tu es sur la page blanche. Affiche le code source (Généralement Ctrl + U ou clique droit sur la page “Afficher le code source”). Si c’est vide alors Symfony ne retourne que 403 et pas une page complété.

Si c’est peu remplit, ben c’est pareil. Il faut que VueJS soit inclut pour que VueJS puisse agir.

403 => L’authentification ne change rien. C’est une page interne par exemple. Interdit à ce “User-Agent“, interdit au IP externe, …

401 => Pas les droits suffisants. L’authentification pourrait résoudre le problème.

Dernier point: Je ne fais pas de PHP.

+0 -0

AH ! Ca marche ! J’ai bien récupéré la page normale d’erreur, qui me donne bien cette fois une erreur 401 et non 403. Là où ça me chagrine, c’est que je n’ai aucune idée de ce qui a pu corriger le problème tout à coup : commenté toute ligne de configuration non absolument indispensable, vidé le cache pour énième fois. Et pouf. Il faudra que je dé-commente une par une les lignes pour voir ce qui a posé problème.

Merci d’avoir attiré mon attention sur la mauvaise erreur générée, ça m’a globalement confirmé que le souci vient de Symfony et non Vue.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte