Discussion:
Modifier une session a partir de son id
(trop ancien pour répondre)
Julien Arlandis
2011-01-08 21:06:09 UTC
Permalink
Bonjour,

Connaissez vous un moyen d'accéder aux variables de session de n'importe
quel utilisateur à partir de son id de session (session_id()) ?
Mickael Wolff
2011-01-08 21:59:52 UTC
Permalink
Post by Julien Arlandis
Bonjour,
Connaissez vous un moyen d'accéder aux variables de session de n'importe
quel utilisateur à partir de son id de session (session_id()) ?
Ça dépend de ton backend. Si tu utilises le backend par défaut de
PHP, il suffit d'ouvrir le fichier contenant la session (ça dépend de la
configuration du module de session et des options de compilation de
PHP). Sinon, il faut regarder la documentation liée au backend que tu
utilises.
Julien Arlandis
2011-01-09 13:11:14 UTC
Permalink
Post by Julien Arlandis
Bonjour,
Connaissez vous un moyen d'accéder aux variables de session de n'importe
quel utilisateur à partir de son id de session (session_id()) ?
Ça dépend de ton backend. Si tu utilises le backend par défaut de PHP,
il suffit d'ouvrir le fichier contenant la session (ça dépend de la
configuration du module de session et des options de compilation de
PHP). Sinon, il faut regarder la documentation liée au backend que tu
utilises.
Effectivement, dans ma config chaque session est stockée dans un fichier
situé dans /var/lib/php/sess_+session_id , mais existe t-il des outils
pour manipuler ces fichiers ?

statut|s:11:"A la maison";id|s:1:"1";actif|b:1;group|s:3:"999";
check|i:78578930;

Le format semble être le suivant :
nom_variable + '|' + caractère parmi {b(oolean), i(nteger), s(tring),
...} + valeur + '\n'. Pas très sympathique à manipuler...
Mickael Wolff
2011-01-10 10:23:55 UTC
Permalink
Post by Julien Arlandis
statut|s:11:"A la maison";id|s:1:"1";actif|b:1;group|s:3:"999";
check|i:78578930;
nom_variable + '|' + caractère parmi {b(oolean), i(nteger), s(tring),
...} + valeur + '\n'. Pas très sympathique à manipuler...
Le format est décrit ici :
http://php.net/manual/fr/language.oop5.serialization.php
Jean-Francois Ortolo
2011-01-09 14:39:06 UTC
Permalink
Post by Julien Arlandis
Bonjour,
Connaissez vous un moyen d'accéder aux variables de session de n'importe
quel utilisateur à partir de son id de session (session_id()) ?
Ça dépend de ton backend. Si tu utilises le backend par défaut de PHP,
il suffit d'ouvrir le fichier contenant la session (ça dépend de la
configuration du module de session et des options de compilation de
PHP). Sinon, il faut regarder la documentation liée au backend que tu
utilises.
Bééééééhhhhhh....

Cà veut dire qu'un site comportant des accès par login/password, doit
nécessairement crypter la ou les données certifiant l'authentification
d'un abonné ? Et ce cryptage doit nécessairement dépendre de données
propres à chaque abonnés, pour être efficace ?

Merci beaucoup de l'info, celà confirme des indications que j'avais
lues il y a plusieurs mois sur la façon de certifier l'authentification
d'un abonné.

Encore faut-il avoir l'id de session, mais le post initial fait comme
si ce problème était déjà résolu...

Bien à vous.

Amicalement.

Jean-François Ortolo
--
Visitez mon site gratuit donnant des Statistiques,
des Pronostics et des Historiques Graphiques
sur les Courses de Chevaux:
http://www.pronostics-courses.fr
Mickael Wolff
2011-01-10 10:23:55 UTC
Permalink
Post by Jean-Francois Ortolo
Cà veut dire qu'un site comportant des accès par login/password, doit
nécessairement crypter la ou les données certifiant l'authentification
d'un abonné ? Et ce cryptage doit nécessairement dépendre de données
propres à chaque abonnés, pour être efficace ?
Ça dépend. Si tu es en hébergement mutualisé, selon les options de
configuration de PHP, tu peux avoir accès aux fichiers de session des
colocataires. Dans ce cas, il y a un risque certain de compromission des
données.

Celà dit, le mécanisme de session est destiné à fournir un mécanisme
d'état que HTTP ne fourni pas. Les mots de passe n'ont donc pas de
raison d'être dans les sessions.

Et enfin, chiffrer la session, en sachant que la serialisation des
données ajoute déjà un overhead non-négligeable, n'est pas forcément
pertinent.
Pascal
2011-01-11 08:46:25 UTC
Permalink
Post by Mickael Wolff
Ça dépend. Si tu es en hébergement mutualisé, selon les options de
configuration de PHP, tu peux avoir accès aux fichiers de session des
colocataires. Dans ce cas, il y a un risque certain de compromission des
données.
Sérieusement ?
Il y aurait encore des hébergeurs avec des configs à la noix qui
permettraient ce genre de hacking ?
Si tu as des sources d'infos, je suis preneur.
--
Cordialement,
Pascal
Mickael Wolff
2011-01-12 06:07:30 UTC
Permalink
Post by Pascal
Sérieusement ?
Il y aurait encore des hébergeurs avec des configs à la noix qui
permettraient ce genre de hacking ?
Si tu as des sources d'infos, je suis preneur.
C'est pour ce genre de raisons qu'il faut tester son hébergeur, et ne
pas hésiter à changer lorsqu'on trouve quelque chose de bizare. Pour ce
que ça coûte un hébergement mutualisé.
Tout les hébergeurs n'ont pas les moyens ou les compétences pour
configurer correctement un hébergement mutualisé. Ou encore, ceci peut
ne pas faire partie de la politique de sécurité. En hébergement
mutualisé, tu sais que tu partage un même processus (et donc un même
utilisateur) avec d'autres clients. À partir de là, il ne faut pas
s'attendre à une parfaite étanchéité.
Julien Arlandis
2011-01-11 21:42:45 UTC
Permalink
Post by Mickael Wolff
Post by Jean-Francois Ortolo
Cà veut dire qu'un site comportant des accès par login/password, doit
nécessairement crypter la ou les données certifiant l'authentification
d'un abonné ? Et ce cryptage doit nécessairement dépendre de données
propres à chaque abonnés, pour être efficace ?
Ça dépend. Si tu es en hébergement mutualisé, selon les options de
configuration de PHP, tu peux avoir accès aux fichiers de session des
colocataires. Dans ce cas, il y a un risque certain de compromission des
données.
Celà dit, le mécanisme de session est destiné à fournir un mécanisme
d'état que HTTP ne fourni pas. Les mots de passe n'ont donc pas de
raison d'être dans les sessions.
Bonjour,

Pour ma part je considère les sessions comme un mécanisme de mémoire
tampon consistant à dupliquer certaines données utilisateurs stockées
dans la base de données qui sont très sollicitées par les scripts, afin
d'économiser des connexions et des requêtes vers la base. Mais est ce
que l'accès en lecture d'une variable de session est plus rapide qu'un
simple select sur une table indexée, c'est ce que j'ai toujours
inconsciemment pensé mais n'ayant jamais fait de mesure peut être que
cette hypothèse est erronée sous certaines conditions. En particulier
quand la BD est hébergée sur le même serveur que php, le gain de
performance est il réel? Au sujet de la connexion à la base, est il
possible que les scripts se partagent la même connexion pour économiser
les authentifications (j'utilise PDO) ?
Mickael Wolff
2011-01-12 06:07:30 UTC
Permalink
Post by Julien Arlandis
Pour ma part je considère les sessions comme un mécanisme de mémoire
tampon consistant à dupliquer certaines données utilisateurs stockées
dans la base de données qui sont très sollicitées par les scripts, afin
d'économiser des connexions et des requêtes vers la base.
La session n'est pas un système de cache.
C'est un détournement du mécanisme standard des sessions. Une session
est l'ensemble des données relatives à l'état de ton application. Par
exemple, les tokens pour les formulaires, le modèle en cours de
modification ou création (par exemple, une ressource créée à travers
plusieurs formulaires, la sauvegarde automatique temporaire d'un
article, etc).
Lorsqu'on utilise les sessions en base de données, ça va
difficilement réduire les appels à la base de données.
Cette optimisation a priori peut avoir des effets désastreux. Le
back-end par défaut utilises des fichiers sur la machine qui héberge le
processus Apache ou PHP CGI. Ce qui signifie qu'on augmente les IO sur
le disque du serveur qui sert l'application. On sait que l'un des
principaux goulets d'étranglement des applications web est les IO disque
sur le serveur web. C'est pour ça qu'il existe d'autres backend pour les
sessions (Memcache, MySQL, etc). Pour peut que la session soit
lourdement utilisée comme cache applicatif, les serveurs peuvent
s'effondrer sous une forte charge.
Post by Julien Arlandis
Mais est ce que l'accès en lecture d'une variable de session est plus rapide qu'un
simple select sur une table indexée,
Comme toujours en informatique, dans les systèmes complexes : ça
dépend :o)
Post by Julien Arlandis
c'est ce que j'ai toujours
inconsciemment pensé mais n'ayant jamais fait de mesure peut être que
cette hypothèse est erronée sous certaines conditions.
Utiliiser une optimisation sans faire de tests n'est pas une bonne
initiative. Ceci dit, c'est difficile de faire des tests de performance.
Je ne te jeterai pas la première pierre ;)
Post by Julien Arlandis
En particulier quand la BD est hébergée sur le même serveur que php, le gain de
performance est il réel?
Il faut tester. Mais il ne faut pas oublier d'inclure le temps
d'initialisation de la session. La déserialisation des données n'est pas
gratuite.
Post by Julien Arlandis
Au sujet de la connexion à la base, est il
possible que les scripts se partagent la même connexion pour économiser
les authentifications (j'utilise PDO) ?
Dans un même script, une connexion sera unique (tout au moins avec
MySQL). C'est un comportement qui est géré par l'extension.
La connexion à la base de données peut être mutualisée entre les
différents appels à la base de donnée. On peut activer cette
fonctionnalité en utilisant une connexion permanente. *Mais* en
hébergement mutualisé, c'est généralement désactivé. La raison est que,
si tu a 10 000 clients qui conservent une connexion permanente vers la
base de donnée-- ça peut être quelque peu insoutenable. Il ne faut pas
non plus oublier que MySQL resterait aussi à l'écoute, ce qui signifie
qu'il doit aussi allouer des ressources à la connexion permanente. En
fait, les connexions permanentes sont déconseillées sur les systèmes
fortement sollicités. Désactiver Keep Alive sur Apache peut sauver un
serveur du passage à lighttpd.

Il n'y a pas de réponse générale. Il faut tester et s'adapter au
besoins de l'application (ou du site).
Julien Arlandis
2011-01-12 16:48:58 UTC
Permalink
Post by Mickael Wolff
Post by Julien Arlandis
Pour ma part je considère les sessions comme un mécanisme de mémoire
tampon consistant à dupliquer certaines données utilisateurs stockées
dans la base de données qui sont très sollicitées par les scripts, afin
d'économiser des connexions et des requêtes vers la base.
La session n'est pas un système de cache.
C'est un détournement du mécanisme standard des sessions. Une session
est l'ensemble des données relatives à l'état de ton application...
... et à une connexion donnée. Par exemple, si on veut partager une
donnée propre à l'application (comme le nombre de visiteurs) il ne me
semble pas que l'on puisse utiliser l'objet $_SESSION dans ce cas,
quelle serait la solution appropriée dans ce cas?


Par
Post by Mickael Wolff
exemple, les tokens pour les formulaires, le modèle en cours de
modification ou création (par exemple, une ressource créée à travers
plusieurs formulaires, la sauvegarde automatique temporaire d'un
article, etc).
Lorsqu'on utilise les sessions en base de données, ça va difficilement
réduire les appels à la base de données.
Par exemple si on veut afficher le prénom de l'utilisateur sur chaque
page du site, une solution serait de stocker le prénom en session à
chaque authentification de l'utilisateur. Dans ce cas l'appel à la base
de données ne se fait qu'une seule fois : lors de l'authentification.
Post by Mickael Wolff
Post by Julien Arlandis
En particulier quand la BD est hébergée sur le même serveur que php, le gain de
performance est il réel?
Il faut tester. Mais il ne faut pas oublier d'inclure le temps
d'initialisation de la session. La déserialisation des données n'est pas
gratuite.
Quand PHP et Mysql sont sur le même serveur, n'est il pas possible de
supprimer la phase d'authentification étant donné que je suis seul à
exploiter la base sur mon serveur dédié? Et peut on utiliser les sockets
unix dans ce cas pour faire l'économie de TCP/IP qui doit quand même
alourdir la charge?
Mickael Wolff
2011-01-14 14:40:34 UTC
Permalink
Post by Julien Arlandis
... et à une connexion donnée.
C'est ce que j'entendais par application, je me suis mal exprimé, désolé.
Post by Julien Arlandis
Par exemple, si on veut partager une
donnée propre à l'application (comme le nombre de visiteurs) il ne me
semble pas que l'on puisse utiliser l'objet $_SESSION dans ce cas,
quelle serait la solution appropriée dans ce cas?
Ça dépend si on veut quelque chose de fiable ou non.
Post by Julien Arlandis
Par exemple si on veut afficher le prénom de l'utilisateur sur chaque
page du site, une solution serait de stocker le prénom en session à
chaque authentification de l'utilisateur. Dans ce cas l'appel à la base
de données ne se fait qu'une seule fois : lors de l'authentification.
La session n'est pas le bon endroit pour cacher les informations. Si
tu as besoin d'un cache, il faut utiliser un outil comme memcache. La
session est associée à un cookie. Si tu modifie une information qui est
cachée dans la session du même utilisateur, il faut penser à invalider
cette donnée. C'est un des cas d'utilisation où tu veux d'ailleurs
accéder à une autre donnée. Utiliser un vrai système de cache, c'est
pouvoir simplement invalider le cache lorsqu'on met à jour une donnée en
base. Ceci dit, cacher les données en session est tellement répandu
(ainsi que les bogues associés), que je ne peux te jeter la pierre.
Maintenant, utiliser un cache doit avoir une justification. La
première raison est que les caches sont souvent à l'origine de bogues
étranges. La seconde, c'est que l'usage d'un cache peut dégrader les
performances. La mise en place de caches devrait toujours être étudiée.
Comme toute optimisation.
Post by Julien Arlandis
Quand PHP et Mysql sont sur le même serveur,
Je tiens à préciser que, si tu as des problèmes de performance, la
première des choses est de séparer le serveur web du serveur de base de
données. À ce moment là, la question ne se pose pas. Si tu n'as pas de
problèmes de performance, tu peux éventuellement utiliser les sockets
unix pour des raisons de sécurité (supprimer une application réseau sur
la pile IP).
Julien Arlandis
2011-01-16 23:11:04 UTC
Permalink
Post by Mickael Wolff
Post by Julien Arlandis
Par exemple, si on veut partager une
donnée propre à l'application (comme le nombre de visiteurs) il ne me
semble pas que l'on puisse utiliser l'objet $_SESSION dans ce cas,
quelle serait la solution appropriée dans ce cas?
Ça dépend si on veut quelque chose de fiable ou non.
Post by Julien Arlandis
Par exemple si on veut afficher le prénom de l'utilisateur sur chaque
page du site, une solution serait de stocker le prénom en session à
chaque authentification de l'utilisateur. Dans ce cas l'appel à la base
de données ne se fait qu'une seule fois : lors de l'authentification.
La session n'est pas le bon endroit pour cacher les informations. Si tu
as besoin d'un cache, il faut utiliser un outil comme memcache.
J'ai testé memcached et réalisé quelques tests :

<?php
$mem = new Memcache;
$mem->connect('localhost', 11211);

$_SESSION['toto'] = 1;
$mem->set('toto',1);

function get_session($champ)
{
global $mem;
return $mem->get($champ);
}

function get_memcached($champ)
{
return $_SESSION[$champ];
}

$ms = microtime(true);
for($i=0;$i<100000;$i++)
{
$toto = get_session('toto');
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";

$ms = microtime(true);
for($i=0;$i<100000;$i++)
{
$toto = get_memcached('toto');
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";
?>

retourne :

3800 ms (pour memcached)
44 ms (pour les sessions)

L'accès aux données avec les sessions est presque 100 fois plus rapide
qu'avec memcached. Et si j'utilise les sockets unix avec memcached je
passe de 3800 ms à 2800 ms. Bien sûr cela ne signifie pas que memcached
est plus gourmand en ressource que la serialisation, mais les temps de
réponse du fait de l'utilisation des sockets sont nettement plus
importants. Que faut il privilégier, le temps de réponse du script php,
l'utilisation du processeur, la consommation mémoire? Pour information,
je suis en train de coder un site qui a vocation à accueillir un fort
trafic (10000 connectés en simultanés pendant les heures de pointe)
c'est pour cette raison que je suis très soucieux de la montée en charge
du serveur.
Mickael Wolff
2011-01-17 08:34:16 UTC
Permalink
Post by Julien Arlandis
L'accès aux données avec les sessions est presque 100 fois plus rapide
qu'avec memcached. Et si j'utilise les sockets unix avec memcached je
passe de 3800 ms à 2800 ms. Bien sûr cela ne signifie pas que memcached
est plus gourmand en ressource que la serialisation, mais les temps de
réponse du fait de l'utilisation des sockets sont nettement plus
importants. Que faut il privilégier, le temps de réponse du script php,
l'utilisation du processeur, la consommation mémoire? Pour information,
je suis en train de coder un site qui a vocation à accueillir un fort
trafic (10000 connectés en simultanés pendant les heures de pointe)
c'est pour cette raison que je suis très soucieux de la montée en charge
du serveur.
Attention à ce que tu mesures. Le tableau de session est déjà
déserialisé quand on y accède en PHP. La déserialisation se fait à
l'ouverture de la session. Du coup tu utilises un tablean PHP.
Lorsque tu sauvegardes les données dans Memcache, tu sérialises (car
tu ne peux que sauver des chaines de caractères).

10 000 connectés simultanés n'entraîne pas nécessairement un fort
trafic ;) Ceci dit, si ton application doit être scalable, il faudra une
infrastructure scalable (backend de session adapté, caches répartis,
base de données shardable, etc). Et ça sort, je pense, du cadre de ce forum.
Julien Arlandis
2011-01-17 22:26:59 UTC
Permalink
Post by Mickael Wolff
Post by Julien Arlandis
L'accès aux données avec les sessions est presque 100 fois plus rapide
qu'avec memcached. Et si j'utilise les sockets unix avec memcached je
passe de 3800 ms à 2800 ms. Bien sûr cela ne signifie pas que memcached
est plus gourmand en ressource que la serialisation, mais les temps de
réponse du fait de l'utilisation des sockets sont nettement plus
importants. Que faut il privilégier, le temps de réponse du script php,
l'utilisation du processeur, la consommation mémoire? Pour information,
je suis en train de coder un site qui a vocation à accueillir un fort
trafic (10000 connectés en simultanés pendant les heures de pointe)
c'est pour cette raison que je suis très soucieux de la montée en charge
du serveur.
Attention à ce que tu mesures. Le tableau de session est déjà
déserialisé quand on y accède en PHP. La déserialisation se fait à
l'ouverture de la session. Du coup tu utilises un tablean PHP.
Lorsque tu sauvegardes les données dans Memcache, tu sérialises (car tu
ne peux que sauver des chaines de caractères).
Effectivement, c'est ce que je viens de vérifier, cette fois ci j'ai
modifié le php.ini pour rediriger les sessions dans memcache.

<?php

$mem = new Memcache;
$mem->connect('localhost', 11211);

$ms = microtime(true);
for($i=0;$i<10000;$i++)
{
$champ = 'toto'.$i;
$_SESSION[$champ] = 1;
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";

$ms = microtime(true);
for($i=0;$i<10000;$i++)
{
$champ = 'toto'.$i;
$mem->set($champ, 1);
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";
?>

La première boucle retourne 3 ms
et la seconde 386 ms.
Conclusion, la sérialisation ne doit avoir lieu qu'une seule fois, php
doit faire un get à l'ouverture de la session et un set à la fermeture.
Post by Mickael Wolff
10 000 connectés simultanés n'entraîne pas nécessairement un fort trafic
;) Ceci dit, si ton application doit être scalable, il faudra une
infrastructure scalable (backend de session adapté, caches répartis,
base de données shardable, etc). Et ça sort, je pense, du cadre de ce forum.
Pour le backend de session je pense qu'un serveur memcache devrait
largement suffire, pour la répartition des caches je n'ai pas encore
réfléchi à la question, que me conseillez vous? Sur mon site les membres
sont appelés à uploader des documents qui seront accessibles en lecture
via un flush php. Je pense qu'il faudrait stocker les fichiers sur un
serveur à part mais comment éviter le goulot d'étranglement sur les I/O
du disque dur ?
Pour les bases de données j'ai pensé mettre mysql en cluster.
Mickael Wolff
2011-01-19 10:05:12 UTC
Permalink
Post by Julien Arlandis
Conclusion, la sérialisation ne doit avoir lieu qu'une seule fois, php
doit faire un get à l'ouverture de la session et un set à la fermeture.
Tout à fait.
Post by Julien Arlandis
Pour le backend de session je pense qu'un serveur memcache devrait
largement suffire,
Avec Memcache, il y a quelques éléments auxquels il faut prêter
attention à :
- la limite à 1Mo de la valeur associée à la clé
- la volatilité des données
- l'accès non-sécurisé des données (il n'y a pas de mécanisme
d'autentification dans Memcache)
Post by Julien Arlandis
pour la répartition des caches je n'ai pas encore
réfléchi à la question, que me conseillez vous?
L'accès aux données confiées à un cluster Memcache est indiférencié.
En gros, quand tu intéroges un serveur Memcache, il pose la question à
quelques autres serveurs, et donne le résultat cohérent. Je n'ai pas les
détails de l'algo en tête. Mais le code source est très clair et simple.
Quand tu ajoutes un serveur Memcache, il suffit de le dire aux autres
(ou un autre, je n'ai jamais déployé du Memcache, uniquement travaillé
avec).
Post by Julien Arlandis
Sur mon site les membres
sont appelés à uploader des documents qui seront accessibles en lecture
via un flush php. Je pense qu'il faudrait stocker les fichiers sur un
serveur à part mais comment éviter le goulot d'étranglement sur les I/O
du disque dur ?
Raid, proxy, round robin, usine à gaz :o) Mais ce n'est pas le sujet
du forum.
Post by Julien Arlandis
Pour les bases de données j'ai pensé mettre mysql en cluster.
Tu peux tenter de lever un troll sur comp.lang.sgbd si tu t'en sens
le courage :D Ceci dit, regardes les derniers développements de MySQL.
Julien Arlandis
2011-01-14 14:40:34 UTC
Permalink
Post by Mickael Wolff
La session n'est pas un système de cache.
C'est un détournement du mécanisme standard des sessions. Une session
est l'ensemble des données relatives à l'état de ton application.
Je viens de lire qu'en JSP il existait des sessions globales, ça
s'appele des portées "application". Il se trouve que de tels objets me
seraient bien utiles en php, avez vous une idée comment implémenter
correctement de tels objets qui seraient accessibles en lecture et en
écriture par tous mes scripts? C'est quand même étonnant qu'il n'y ait
pas un tableau prévu à cet effet genre $_APPLICATION.
Mickael Wolff
2011-01-15 12:50:10 UTC
Permalink
Post by Julien Arlandis
Je viens de lire qu'en JSP il existait des sessions globales, ça
s'appele des portées "application". Il se trouve que de tels objets me
seraient bien utiles en php,
Dans quel cas ? Et qui s'occupe de mettre à jour ?
Post by Julien Arlandis
avez vous une idée comment implémenter
correctement de tels objets qui seraient accessibles en lecture et en
écriture par tous mes scripts?
Tu peux utiliser une base de données.
Post by Julien Arlandis
C'est quand même étonnant qu'il n'y ait
pas un tableau prévu à cet effet genre $_APPLICATION.
Non, ce n'est pas étonnant. PHP est basé sur un modèle d'exécution
éphémère. À chaque requête, l'application repart de zéro contrairement à
JSP qui est chargé en continue quand on utilise les servlets (tout du
moins avec Tomcat).
Continuer la lecture sur narkive:
Loading...