web-dev-qa-db-fra.com

comment actualiser le jeton Joomla sous forme de AJAX

J'ai un site Web qui utilise un appel AJAX pour connecter un utilisateur. Pour sécuriser cela, j'ai ajouté un jeton au formulaire de connexion - https: // docs. joomla.org/How_to_add_CSRF_anti-spoofing_to_forms

Le problème est que, lorsque l'utilisateur est inactif pendant un moment, la déconnexion automatique de Joomla est déclenchée. Et donc mon jeton ne marche pas.

Comment actualiser le jeton par AJAX avant de passer l'appel de connexion?)

----------------------------------------- ------------ Plus de détails: ----------------------------------- ------------------------

Le fonctionnement normal du formulaire est omis dans AJAX par:

jQuery('#login-user').click(function(e){            
e.preventDefault(); 

Et puis le login AJAX est envoyé:

form = jQuery('#userForm'); 

jQuery.ajax({
    url: 'index.php?option=com_content&format=ajax&view=article&task=loginUser&tmpl=component',
    type: 'post',
    dataType: 'html',
    data: {
        form: jQuery(form).serializeArray()
    },
    async: true,
    success: function(response){
        var result = jQuery.parseJSON(response);

        if ( result.loggedIn == 1 ) {                       
            //User logged in
            jQuery('#loginModal').modal('hide');
            window.location.href = window.location.pathname + window.location.search + window.location.hash;// reload page creates a history entry
        }
        else {                  
            //User not logged in    
            console.log("not");         
        }               
    }
}); 

MAIS: le problème est que, lorsque l'utilisateur est inactif pendant un moment, la déconnexion automatique de Joomla est déclenchée. Et donc mon jeton ne fonctionne pas.

Comment actualiser le jeton par AJAX avant de passer l'appel de connexion?)

2
JonasB

Je voulais répondre à votre question précédente à ce sujet hier, mais quelqu'un a déjà répondu partiellement à votre question. Donc, selon moi, votre champ de jeton de formulaire de connexion d'origine devrait être un peu modifié comme suit:

<form method="post" action="#" id="userForm">
    <label for="username">Brugernavn</label>    
    <input type="text" value="" name="username">    
    <label for="password">Password</label>  
    <input type="password" value="" name="password">
    <?php echo '<input id="token" type="hidden" name="' . JSession::getFormToken($forceNew=true) . '" value="1" />'; ?>

    <button id="login-user">Login</button>
</form>

De cette façon, la fonction de jeton oblige à toujours générer un nouveau jeton qui peut être envoyé avec la requête AJAX à tout moment (votre requête originale AJAX peut aussi être modifiée légèrement) pour transmettre le jeton créé de cette façon et vérifier le jeton dans votre fonction appelée devrait peut-être être reformulé aussi. Peut-être que ceux-ci sont OK comme ils le sont maintenant, vous allez le tester). J'espère que cela peut vous aider dans la question.

À présent, la solution ci-dessus génère un nouveau jeton pour le formulaire uniquement lorsque le site est actualisé. et ce n'est pas ce que vous recherchez, comme nous l'avons découvert un peu plus tard. Et je ne quitterai pas ce sujet sans le fermer si nous y allons maintenant.

Alors, quel est le vrai problème ici?

Bien sûr, comme nous en avons parlé (dans les commentaires ajoutés), vous pouvez obtenir un nouveau jeton avec un appel initial AJAX appel à une fonction de refreshingToken () (qui serait une fonction personnalisée que vous pourriez créer avec quelques lignes de codes), mais cette fonction supprimerait également l'ancien jeton de requête/session et en créerait un nouveau (ce qui impliquerait également une nouvelle session et une nouvelle demande). pour des raisons de sécurité.

Voici le problème et la solution la plus possible de ce que vous voulez accomplir: La vraie solution à votre problème concerne les sessions et pas pour obtenir de nouveaux jetons.

Une fois que vous avez enfin expliqué que vous souhaitez résoudre le problème de l'utilisateur connecté lorsqu'il édite un article, il met un peu plus de temps à terminer l'édition et que cet utilisateur a été déconnecté par le système. veulent qu’ils soient reconnectés sans redirection et perdent leur article inachevé par exemple.

ne solution de travail de ce problème est comment Joomla l'a résolu en maintenant la session en vie avec une fonction Joomla principale.

Par conséquent, si vous appelez la fonction suivante en haut des fichiers de mise en page de vos pages particulières (ou dans votre fichier de mise en forme de formulaire):

JHtml::_('behavior.keepalive');

Ensuite, la session de l’utilisateur sera maintenue active et votre problème sera résolu (on peut le dire), car la session n’expirera pas sur la page de modification de l’article. L’utilisateur ne perdra pas son travail car il ne sera pas déconnecté lors de la rédaction ou de la révision d’un article important.

Maintenant, devez-vous créer votre propre formulaire de connexion AJAX pour ajouter la fonction keepalive () à la page de modification de l'article com_content, par exemple?

Non, vous pas.

GARDER LA SESSION VIVANTE SUR DIFFERENTES PAGES DE JOOMLA

Dans Joomla, en haut du module de connexion (mod_login) le JHtml :: _ ('behavior.keepalive'); est inclus, donc si vous publiez ce module de connexion Sur les pages (ou les menus) Article Edit, par exemple, la session de l'utilisateur restera active, ce qui signifie que votre éditeur ne perdra pas son travail car il ne sera pas déconnecté de sa session, car le La fonction keepalive () (via une fonction javascript) actualise régulièrement le temps de sa session.

et enfin

Si vous le souhaitez, vous pouvez également inclure JHtml :: _ ('behavior.keepalive');); en haut de votre fichier de présentation de formulaire de connexion personnalisé placé sur la page 'modification de l'article'. empêche de déconnecter les utilisateurs lors de l'édition et de perdre un article inachevé aux côtés de votre utilisateur.

ne autre solution possible:

  1. Vous pouvez également créer un plug-in indiquant le temps restant de la session sur les pages de modification d'article d'un module. Il peut également y avoir un bouton permettant de redémarrer la session ou de créer une branche. La classe Joomla/CMS/Session/Session a des fonctions pour ce qui pourrait être appelé (elle devrait aussi être étudiée davantage par moi-même). Ainsi, l'utilisateur, au lieu de se connecter, peut simplement appuyer sur un bouton pour redémarrer la session. (plus tard, j'ai vérifié ces fonctions de session et, malheureusement, start (), restart (), fork (), toutes ces fonctions détruisent la session en cours. Ce ne sont donc pas des solutions efficaces. problème en question).

Je suis désolé pour la très longue description, mais c’était le seul moyen d’éliminer le problème et le sujet à un niveau acceptable. J'espère que cela va clarifier le sujet et vous aider.

4
Zollie

Jouer avec les sessions n’est généralement pas très sûr; vous pouvez créer plus de problèmes en essayant de trouver une solution.

Vous pouvez effectuer l’une des tâches suivantes (ou les deux):

  • Augmentez la durée de vie de la session sous System, Global Configuration À un nombre plus élevé, tel que 1440 (1 jour). Cela minimisera le problème, mais ne l'éliminera pas. Un autre problème de cette approche est que vous pouvez risquer d’inonder votre table de session si votre site web génère un trafic énorme. Voir ici .
  • Ajoutez à votre modèle une demande Ajax qui chargera n'importe quelle page de votre site Web toutes les 30 minutes environ.

La réponse précédente mentionnait l'utilisation de JHtml::_('behavior.keepalive');, qui devrait également fonctionner techniquement, mais je me souviens (et je me trompe peut-être) que cela ne fonctionne pas bien lorsque la mise en cache des pages est activée.

4
itoctopus