Jump to content

Prestashop déconnexion client impossible


kezako_12

Recommended Posts

Bonjour,

Je viens d'être confronté au problème de déconnexion du client avec la version 1.7 de Prestashop. Selon ce que j'ai pu lire sur le web, ce problème existe avec les versions antérieures.

Voici ce que j'ai pu observer :

La connexion d'un client est enregistrée dans un cookie qui est le cookie frontend. La durée de vie de ce cookie est paramétrable dans l'admin est il est réglé par défaut à 480 heures soit 20 jours.

Lorsqu'un client se connecte, il y a deux cas de figure :

cas n° 1 :  il possède déjà un compte et se connecte avec ses identifiants (qui sont conservés en cache dans son navigateur pendant 20 jours par défaut)

cas n° 2 : il ne possède pas de compte, il en créé un et il est connecté.

Etude des deux cas :

Cas n° 1 : si le client déjà inscrit se connecte à son compte pendant cette période  de 20 jours (ce qui signifie que ses identifiants sont en cache), la déconnexion ne fonctionnera pas, il sera obligé de vider le cache de son navigateur pour pouvoir se déconnecter (il parait difficile d'obliger le client à effectuer cette manipulation, cela ne fait pas très sérieux !... :wacko:)

Cas n°2 : si le client vient de créer son compte, à la fin de ses achats le lien de déconnexion fonctionnera normalement.

En revanche, si ce même client décide 10 minutes après, ou le lendemain de refaire un achat, la déconnexion ne fonctionnera pas tant que la période de 20 jours, à l'issue de laquelle les données en cache seront automatiquement effacées, ne sera pas passée. Et on se retrouve dans le cas n° 1 !...

Pourquoi ?

Plaçons nous dans le cas ou le client vient de créer son compte ou que c'est client qui a déjà un compte et qu'il se connecte avec ses identifiants après le délai de validité des cookies :

Le lien de déconnexion ressemble à quelque chose comme ceci :

<a href="https://www.maboutique.fr /?mylogout "> Déconnexion </a>

Lorsqu'il va cliquer sur ce lien, celui-ci sera placé dans le cache du navigateur (ceci est observable dans la console debug du navigateur – Chrome, Firefox, onglet Network).

 

image.thumb.png.b26bfd187b09b0bb64d72e84f752e7ff.png

 

Une fois en cache, ce lien ne fonctionne  plus et la déconnexion devient impossible tant que ce cache n'est pas vidé (manuellement ou automatiquement après la période de validité définie dans l'admin).

Il est possible également, de vérifier dans le navigateur que le cookie frontend n'est pas modifié après un clic sur le lien de déconnexion : vous y trouverez la même valeur que celle qui a été créée lors de la connexion.

Pour vous en convaincre, si vous êtes dans ce cas de figure, faites l'expérience suivante :

 

image.thumb.png.5422f39d91ddcb28dda94f47e75bc2a4.png

 

Dans la console de votre navigateur, onglet Network, cochez la case "Disable cache", et cliquez à nouveau sur "Déconnexion". Et là ? Miracle, la déconnexion fonctionne, non ?

Ce qui tendrait à prouver que l'on est face à un problème… de cache

(Attention cependant, cette manip ne fonctionne que lorsque la console de debug est active)

Pour ceux qui veulent en savoir plus, la méthode mylogout() est définie dans le fichier maboutique\classes\Customer.php et elle est appelée dans le fichier maboutique\classes\controller\FrontController.php.

Cette méthode ($this->context->customer->mylogout(); est appelée dans un bloc if, elle est suivie de l'instruction

Tools::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null);

Qui a pour but de rediriger le visiteur vers la page à partir de laquelle il a cliqué sur le lien "Déconnexion". Nous y reviendrons plus bas**…

Pour éviter ce problème de mise en cache, j'ai trouvé sur le net une solution qui consiste à "dire" au serveur de ne pas mettre en cache dans le navigateur certains types de fichier. Ces instructions sont à placer dans le fichier .htaccess à la racine du site :

<IfModule mod_headers.c>

<FilesMatch "\.(php)$">

            Header set Cache-Control "no-cache, no-store, must-revalidate"

            Header set Pragma "no-cache"

            Header set Expires 0

</FilesMatch>

</IfModule>

Tous les fichiers dont l'extension est php ne seront pas mis en cache. Cette astuce fonctionne mais elle est un peu "brute" car elle va toucher tous les fichiers php de votre site. J'ai donc creusé un peu plus pour tenter de trouver une solution plus "light".

**Revenons à l'instruction de redirection placée dans le maboutique\classes\controller\FrontController.php :

j'ai constaté que c'est cette instruction qui, lorsqu'elle est exécutée place la méthode mylogout() dans le cache du navigateur.

Il suffit de la placer en commentaire pour que le problème de déconnexion disparaisse définitivement sans créer de dysfonctionnement sur le site. Comme décrit plus haut, cette instruction a pour seul but de renvoyer le visiteur sur la page à partir de laquelle il a cliqué sur le lien de déconnexion. Sans elle, le visiteur sera simplement redirigé vers la page d'accueil, ce qui ne présente pas un inconvénient majeur.

Il est a noter que parmi toutes les méthodes qui concernent le compte client (mon-compte, connexion?back=my-account, mylogout()) seule la méthode mylogout() est mise en cache.

Pourquoi ? Mystère… Il faudrait creuser d'avantage pour tenter de comprendre, quant à moi, je n'ai pas poussé plus loin les investigations. Si cet article est lu par un développeur Prestashop, peut-être aurons-nous une explication…

Dernier point :

Confronté à ce problème sur un site hébergé, avant d'avoir trouvé la solution présentée ci-dessus, j'ai rapatrié ce site pour l'installer en local sur mon serveur EasyPhp. Il s'avère que ce problème n'existe pas sur serveur en local : la méthode mylogout() n'est jamais mise en cache…

Sans doute une piste à creuser ?...

J'espère avoir été assez clair dans mes explications. Si, de votre côté vous avez des informations qui pourraient compléter cet article, n'hésitez pas à publier !

https://www.fuzy-conceptweb.fr/

 

 

 

Edited by kezako_12 (see edit history)
  • Thanks 1
Link to comment
Share on other sites

Bonjour

Je suis bien conscient que ce fonctionnement est anormal ! Je cherche à comprendre ce qui ne va pas.

Le fait est que nous sommes nombreux à constater ce fonctionnement anormal. Existe-t-il une solution ?

Qu'entendez-vous par "cache agressif" ?

 

Link to comment
Share on other sites

Bonjour,

Je viens de trouver LA solution à mon problème !

Il s'agissait bien d'un "cache agressif" comme le disait à juste titre doekia hier.

Je m'explique :

Ma boutique en développement est installée dans un sous-dossier de mon hébergement perso. La piste de la mise en cache anormale de la méthode mylogout() est la bonne, la question que je me posais depuis un moment : "pourquoi cette méthode est mise en cache ?"

La réponse est : le .htaccess, mais pas celui que je croyais à savoir celui de mon installation Prestashop, mais celui qui se trouve de la racine de mon hébergement !!

Toutes les instructions placées dans ce fichier s'appliquent forcément à tous les sous-dossiers, y compris celui ou est installé ma boutique. Et dans ce fichier, il y avait l'instruction "ExpiresDefault "now plus 1 month". Et bing ! :o Par défaut, tous les documents du site sont en cache 1 mois !! :wacko:

Voilà pourquoi lorsque je plaçais les instructions 

<IfModule mod_headers.c>

<FilesMatch "\.(php)$">

            Header set Cache-Control "no-cache, no-store, must-revalidate"

            Header set Pragma "no-cache"

            Header set Expires 0

</FilesMatch>

</IfModule>

dans le .htaccess de ma boutique, tout fonctionnait normalement, car j'écrasais le ExpiresDefault pour les fichiers de type php.

Voilà ! Si cela peut servir à quelqu'un...

Edited by kezako_12 (see edit history)
  • Like 2
Link to comment
Share on other sites

  • 2 months later...

Bonjour,

Je déterre un peu ce topic parce que ça fait un moment que je cherche une solution sur ce que vous décrivez.

J'ai tenté la modification dans le FrontController.php mais elle n'a pas suffit. Dans la fonction init() j'ai ceci :

if (isset($_GET['logout']) || ($this->context->customer->logged && Customer::isBanned($this->context->customer->id))) {
	$this->context->customer->logout();

	Tools::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null);
} elseif (isset($_GET['mylogout'])) {
	$this->context->customer->mylogout();
	Tools::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null);
}

J'ai commenté les deux lignes :

Tools::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null);

Mais ça n'a pas réglé le problème. Par contre, l'ajout du code dans le .htaccess a fonctionné :

<IfModule mod_headers.c>
  <FilesMatch "\.(php)$">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
  </FilesMatch>
</IfModule>

Deux questions du coup :

1) Puisque ce n'est pas la solution idéale, quelles sont les risques encourus par la modification du .htaccess de cette manière ?

2) J'ai envoyé le lien de cette discussion à mon infogérant qui m'a répondu qu'il n'y avait pas de cache au niveau serveur.
La structure du serveur c'est /var/www/nom_utilisateur/dossier_racine_où_pointe_le_dns/tous_les_fichiers_prestashop.
Le fichier .htaccess se trouve donc dans /var/www/nom_utilisateur/dossier_racine_où_pointe_le_dns/

Du coup, le .htaccess fonctionne mais surcharge quelque chose de plus bas niveau, non ?

En tout cas, un grand merci d'avoir pris le temps d'apporter ces solutions à la communauté !

Link to comment
Share on other sites

Lorsqu'il n'est pas possible de ce déconnecter c'est le reflet d'une maladie sur votre site.

Générale ceci a à voir avec les cache. Vous devez impérativement donner un maximum d'information technique si vous souhaitez une réponse pertinente.

Url par exemple, n'auriez vous pas mis des cdn, un gateway, firewal, proxy, ... que sais-je

Link to comment
Share on other sites

Bonjour,

Je vais essayer d'être le plus clair possible :

Vous avez écrit :

"Du coup, le .htaccess fonctionne mais surcharge quelque chose de plus bas niveau, non ?" 

C'est presque ça ! En réalité, il surcharge les htaccess de plus haut niveau (celui placé à la racine du www du serveur)

Ma situation était la suivante :

Sur mon hébergement, j'ai un site en ligne sous la racine www et un site PS en développement dans le sous-dossier : www/demo/

Le dossier racine www contient un .htaccess lié au site en ligne et le sous dossier www/demo contient également un .htaccess lié au fonctionnement du site PS.

Etant donné qu'un .htaccess applique toutes ses directives au dossier courant et à tous ses sous-dossiers , les directives de ce htaccess s'apliquaient également au dossier www/demo.

Dans mon htaccess placé à la racine du site, j'avais la directive "ExpiresDefault "now plus 1 month". Du coup, cette directive s'aplliquait également au sous-dossier www/demo/ de mon site PS.

Le ExpiresDefault s'applique à tous les éléments du site et écrase ainsi les directives du genre :

ExpiresByType text/html "access plus 6 month"
ExpiresByType text/css "access plus 6 month", etc...

De ce fait, la méthode mylogout() (qui est une méthode php) était mise en cache alors qu'elle ne devait pas y être, empêchant ainsi la deconnexion du client.

Le fait de placer le code 

<IfModule mod_headers.c>
  <FilesMatch "\.(php)$">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
  </FilesMatch>
</IfModule>

dans le .htacces du sous-dossier www/demo/ (site PS en développement) celui-ci surchargait la directive ExpiresDefault "now plus 1 month du htacces à la raine www et la deconnexion fonctionnait.

A mon avis, le fait de surcharger le htaccess de la racine du site avec cette solution ne présente pas d'inconvénient majeur, si ce n'est que cela alourdi inutillement le code.

Pour ce qui me concerne, j'ai supprimé la directive ExpiresDefault "now plus 1 month dans le htacces à la racine www, j'ai viré la surcharge dans le htaccess du dossier www/demo/ et tout est rentré dans l'ordre.

J'avais pas mal galéré avec ce problème et c'est doekia qui m'a mis sur la voie... (merci à lui au passage)

Je confirme également que les hébergeurs ne mettent pas de cache sur les serveurs, j'avais également posé la question au mien...

Voilà, en espérant avoir répondu à vos attentes...

 

 

Link to comment
Share on other sites

1 hour ago, kezako_12 said:

Ma situation était la suivante :

Sur mon hébergement, j'ai un site en ligne sous la racine www et un site PS en développement dans le sous-dossier : www/demo/

Le dossier racine www contient un .htaccess lié au site en ligne et le sous dossier www/demo contient également un .htaccess lié au fonctionnement du site PS.

Merci pour le retour @kezako_12.

J'ai été vérifié sur mon serveur, de la racine ( / ) à mon dossier Prestastashop ( /var/www/user/dossier_prestashop ) je n'ai qu'un seul .htaccess qui est justement à la racine du site Prestashop.

Donc à priori pas de surcharge d'un .htaccess par un autre... Pourtant cela fonctionne en faisant ça !

Dans ce cas, je pense qu'il y a un problème au symptôme identique mais pas de la même source. Du coup...

1 hour ago, doekia said:

Lorsqu'il n'est pas possible de ce déconnecter c'est le reflet d'une maladie sur votre site.

Générale ceci a à voir avec les cache. Vous devez impérativement donner un maximum d'information technique si vous souhaitez une réponse pertinente.

Url par exemple, n'auriez vous pas mis des cdn, un gateway, firewal, proxy, ... que sais-je

@doekia, à force d'écrire et réécrire mes posts j'en oublie les bases... Désolé...

URL du site https://tinyurl.com/y5eeygmp
Version de Prestashop : 1.6.1.4
CDN / Proxy / Gateway : non
Firewall, je vous laisse juger de la réponse de mon infogérant : "il y a bien un firewall, mais il n'a pas d'impacter sur le cache de votre site. Nous avons restart le processus php-fpm afin de voir si cela corrige vote problème."

J'ai fait un test depuis leur restart et sans la modification du .htaccess, ça ne fonctionne pas... J'ai bien du mal à trouver un début de piste.

Merci pour vos retours !

 

Link to comment
Share on other sites

On 3/2/2019 at 4:38 PM, kezako_12 said:

@Thomas

Est-ce que vous n'auriez pas une instruction ExpiresDefault "now plus xxx" quelque part dans le .htacces ?

Et voilà ! Merci @kezako_12

Le .htaccess est sans doute optimisable parce qu'il est assez long et j'ai trouvé ceci dedans :

<IfModule mod_expires.c>
    ExpiresActive On
	AddType image/x-icon .ico
	# Images
	ExpiresByType image/jpeg "access plus 1 month"
	ExpiresByType image/gif "access plus 1 month"
	ExpiresByType image/png "access plus 1 month"
	ExpiresByType image/webp "access plus 1 month"
	ExpiresByType image/svg+xml "access plus 1 month"
	ExpiresByType image/x-icon "access plus 1 year"
	# Video
	ExpiresByType video/mp4 "access plus 1 month"
	ExpiresByType video/mpeg "access plus 1 month"
	# CSS, JavaScript
	ExpiresByType text/css "access plus 1 week"
	ExpiresByType text/javascript "access plus 1 week"
	ExpiresByType application/javascript "access plus 1 week"
	ExpiresByType application/x-javascript "access plus 1 week"
	# Others
	ExpiresByType application/pdf "access plus 1 month"
	ExpiresByType application/x-shockwave-flash "access plus 1 month"	
	ExpiresDefault "access plus 1 month"
</IfModule>

J'ai évidemment enlevé le bout de code que vous aviez fourni dans votre message initial et j'ai commenté la ligne ExpiresDefault "access plus 1 month". Tout rentre dans l'ordre !

Par contre, ce que je ne m'explique pas c'est pourquoi chez moi, comme pour beaucoup de client cela pose problème, mais pour d'autres comme @doekia cela fonctionne normalement...

Merci infiniment à vous deux en tout cas !

Link to comment
Share on other sites

Que vient faire cette ligne ici:

ExpiresDefault "access plus 1 month"

Supprime là, d'ailleurs le mieux est surement de regénérer le .htaccess normal de prestashop (desactiver les url simplifiées, enregister, réactiver, enregistrer)

 

Link to comment
Share on other sites

  • 2 weeks later...

Une de mes premières contributions mais il a fallu que je trouve comment regler ce soucis egalement. 

Voici ma solution, je n'ai touché qu'à la seconde partie de l'instruction et cela a réglé le soucis et redirige le client sur la page d'accueil  : 

 if (isset($_GET['logout']) || ($this->context->customer->logged && Customer::isBanned($this->context->customer->id))) {

            $this->context->customer->logout();

 

            Tools::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null);

        } elseif (isset($_GET['mylogout'])) {

            $this->context->customer->mylogout();

            Tools::redirect(index);

        }

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...