Sessions et cookie (encore, désolé)

Sessions et cookie (encore, désolé) - PHP - Programmation

Marsh Posté le 22-02-2005 à 23:20:06    

Encore un sujet sur les sessions et les cookies, j'en suis désolé.  [:petrus75]  
Mais j'ai un peu cherché et j'ai pas trouvé réponse à mes questions.
 
Voilà mon problème : actuellement j'utilise pour authentifier les utilisateurs de mon site en PHP les sessions. C'est à dire que je lis les users/mdp sur une base de donnée et j'enregistre les données envoyées par l'utilisateur via méthode POST en faisant un simple :

Code :
  1. session_register("username" );
  2. session_register("password" );


Evidemment, au bout d'un certains temps (30 minutes je crois, dépend de la conf de PHP), les données s'effacent et alors l'utilisateur se retrouve à nouveau sur la page de login.
 
Ma première question déjà c'est qu'actuellement pour les pages que je veux protéger, je fais un bête :

Code :
  1. session_start();
  2. if(!isset($_SESSION['username'])) {
  3.       header("Location: index.php" );
  4.       exit;
  5. }


Déjà, est-ce que c'est la bonne méthode ? Je crois que c'est pas vraiment une très bonne méthode du point de vue de la sécurité ? non :??:
 
 
Ma seconde question porte sur les cookies, qui si j'ai bien compris peuvent me servir pour que l'utilisateur n'entrent plus ses informations à chaque fois. (arrêtez moi si j'ai tort ! ;)) Mon problème n'est pas la création du cookie, ça marche sans problème, avec un coup de md5 au cas où. Mon problème, c'est comment utiliser les informations du cookie pour protéger mes pages et pour le login ? Comment faire pour faire en sorte que si le cookie est présent chez l'utilisateur, alors on affiche toute la page index.php, sinon on le redirige sur login.php ?
Et par rapport aux sessions ? Je laisse mon if(!isset($_SESSION['username']) sur les pages à protéger ? Ou je dois remplacer par un if(!isset($_COOKIE['username']) ?
 
En fait c'est plus un problème de méthode que de technique je pense ;)... Genre comment il faut faire en règle générale ? :D
 
Merci  :jap:


Message édité par vanilla le 22-02-2005 à 23:22:02

---------------
Membre du Front de Libération de Datoune | Soutenez le FLD | A Tribute To Datoune
Reply

Marsh Posté le 22-02-2005 à 23:20:06   

Reply

Marsh Posté le 22-02-2005 à 23:28:48    

session_register est deprecated :o
utilise directement le tableau superglobal $_SESSION[]


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 22-02-2005 à 23:39:26    

C'est noté :jap:


---------------
Membre du Front de Libération de Datoune | Soutenez le FLD | A Tribute To Datoune
Reply

Marsh Posté le 23-02-2005 à 11:37:59    

J'ai mal posé mes questions :??:

Reply

Marsh Posté le 23-02-2005 à 12:24:18    

Snif, j'avais commence un tres beau post sur comment je faisais, mais je me suis rendu compte que je raccontait plutot ma vie que de repondre a la question :D
 
Concernant tes questions :
 
1) Personnellement je ne vois aucune faille apparente dans ta facon de verifier si l'utilisateur est logue. Il faudrait neanmoins verifier ta procedure de logout. Il faut t'assurer que dans ta procedure de logout tu "effaces" bien la variable "username" et "password".
[Ma vie]
Moi j'utilisais un boolean "loged" pour savoir si l'utilisateur etait logue ou non (en plus du username et du pass). Mais lors de la procedure du logout je ne faisais que "reset" "loged" et "password" mais pas "username". Du coup j'ai eu un effet de bord dans une de mes pages. Donc a faire attention a la procedure du login out
[/Ma vie]
 
2) Je pense que la meilleure facon de faire ce que tu veux c'est que tu crees une fonction "login". Ensuite suffit d'utiliser cette fonction dans ta phase de login.
Elle peut par exemple ressembler a cela :

Code :
  1. function login($user, $pass, $coded=false) {
  2.   $ret = false;
  3.   $pass = ($coded)?$pass:md5($pass); // Si le pass n'est pas code, on  
  4.   // le code nous
  5.   $qry = 'SELECT * FROM users WHERE user="'.$user.'" AND password="'.$pass'"';
  6.  
  7.   $result=@mysql_query($qry);
  8.   $res=@mysql_fetch_assoc($result);
  9.   if ($res===false) { // on devrait plutot tester $result + $res, mais on ne
  10.   // faisant que le test sur $res on "fusionner" 3 tests :
  11.   // $result est valide ? $res est valide ? $res est non nul ?
  12.   // ici tu peux egalement metre du code de gestion en cas d'erreur lors
  13.   // de la connexion a la base de donnes. Tu peux par exemple loger l'erreur dans un fichier au lieu de l'afficher
  14.   // Il vaut mieux loger l'erreur dans un site de "production" et l'afficher dans un site de "test" ou "conception".
  15.   unset($_SESSION['username']);
  16.   unset($_SESSION['password']);
  17.   $ret = false;
  18.   } else {
  19.      $_SESSION['username']=$res['user'];
  20.      $_SESSION['password']=$res['password'];
  21.      $ret = true;
  22.   }
  23.   return $ret;
  24. }


Apres il suffit de verifier si le cookie est present chez l'utilisateur (avec $_COOKIE par exemple). Ensuite tu passe les parametres du cookie a la fonction login, par exemple comme ca :

Code :
  1. require_once('functions_login.php');
  2. // ...
  3. if (isset($_COOKIE['moncookie'])) {
  4.   $cookie = $_COOKIE['moncookie'];
  5.   $res = login($cookie['username'],$cookie['password'],true); // Le mot de passe doit etre stocke "code" (le md5 du pass par exemple)
  6.   if (!$res) {
  7.     // Login a echoue
  8.     header('Location: login.php');
  9.   }
  10. }
  11. // ...


 
2b)(ou 3) Je te conseille de plutot laisser ton if(isset($_SESSIOM... Pour la simple est bonne raison que c'est toi qui "maitrise" la session, alors que le cookie tu le maitrises pas forcement ... Donc en gardant le isset sur la session tu t'evites de mauvaises surprises (il est possible de modifier un cookie sur son navigateur, donc les cookies ne sont pas dignes de confiance).
 
Pour te faciliter la vie, je te conseille de plutot faire soit une page "dedie" au controle du login, soit une fonction qui controle ca.
Comme ca, quand tu veux "proteger" un page il te suffit de faire un truc du genre :

Code :
  1. require_once('control.php');
  2. // ou
  3. require_once('functions_login.php');
  4. control();


Il vaut mieux utiliser des "require_once" lorsqu'il s'agit d'includes "critiques". En effet, php, s'il n'arrive pas a inclure le fichier voulu (pour une quelconque raison) va faire un "die" au lieu de continuer l'execution. Il serait embetant que le site affiche la partie protegee, si le fichier devant controler l'access est manquant ou endomage :D .
 
Les divers codes que j'ai mis en exemple ont ete crees "on the fly". Je ne les ai pas testes, donc il peuvent contenir des erreurs ou autres bugs. :D
 
[edit]
A plus de try, catch, snif :/
[/edit]


Message édité par cerel le 23-02-2005 à 16:54:45
Reply

Marsh Posté le 23-02-2005 à 12:46:05    

Merci pour cette réponse, j'ai appris des choses. Je vais voir un peu tout ça  :jap:  
 
Sinon pour mon logout.php j'utilise session_destroy qui je crois est assez efficace puisqu'elle détruit toutes les variables.


Message édité par vanilla le 23-02-2005 à 12:46:39
Reply

Marsh Posté le 23-02-2005 à 13:10:26    

Question débile :

Code :
  1. <?php require_once('../private.php'); ?>


Marche pas, pourquoi  :??: Apparemment le ../ l'embête mais j'ai pas vraiment envie de foutre le private.php dans chaque sous répertoire :D

Reply

Marsh Posté le 23-02-2005 à 13:11:40    

Certains hébergeurs empêchent le "../" pour raison de sécurité.

Reply

Marsh Posté le 23-02-2005 à 13:31:05    

De totue façon, l'hébergeur c'est moi [:ddr555]
 
Non mais en fait ça vient de moi, je suis con, c'est que j'include à partir de l'index.php donc forcément si je vais dans le repertoire parent, ya pas le private.php :D
 
Bizarre en fait des fois ça marche, des fois je me paye un fichier inconnu :heink:
 
re edit: c'est bon en fait  [:dawa]


Message édité par vanilla le 23-02-2005 à 16:00:43
Reply

Marsh Posté le 23-02-2005 à 13:55:49    

Ce que tu peux aussi faire, c'est utiliser "ini_set" pour modifier "dynamiquement" ton "include_path".
Dans le genre tu peux faire ca :

Code :
  1. $tmppath = ini_get('include_path');
  2.   $res = @init_set('include_path',$tmppath.':'
  3.          .$_SERVER['document_root'].'/includes');
  4.   // Petite remarque, sur linux il faut utiliser ':' pour separer les  
  5.   // repertoires dans un path, sur windows faut utiliser ';'.
  6.   // Alors attention a l'os du serveur.
  7.   if ($res===false) { // attention, faut egalement tester le type donc ===
  8.     // impossible de changer l'include path
  9.   } else {
  10.   // suite du traitement
  11.   }


De cette facon tu ajoutes le repertoire "/includes" a include path, comme ca a chaque fois que tu fais un include, php va d'abord essayer de trouver le fichier dans l'include path. Comme ca tu peux garder la meme "ligne" partout.
 
Sinon ce que tu peux faire c'est utiliser ta propre fonction d'include. Par exemple quelque chose comme ca :

Code :
  1. function myInclude($fic, $root=false) {
  2.   $path = $_SERVER['document_root']. ($root)?'':'/includes/';
  3.   include($path.$fic);
  4. }


Cette fonction s'occupe d'utiliser le "bon" path. Si on l'appele comme ca "myInclude('fonctions.php');" alors il va faire ca "include('chemin/vers/le/script/includes/'.'fonctions.php');"
Mais si tu l'appelles comme ca "myInclude('/includes/fonctions.php',true);" il va egalement inclure le meme fichier mais sans que la fonction rajoute elle le "includes".
 
Apres faut voir la methode qui te convient le mieux.
 
[edit]
A pu de try catch, snif :/
[/edit]


Message édité par cerel le 23-02-2005 à 16:48:27
Reply

Marsh Posté le 23-02-2005 à 13:55:49   

Reply

Marsh Posté le 23-02-2005 à 14:04:30    

Tiens, je connaissais pas le try / catch... c'est 100% php5 ?


---------------
« Lorsque le bûcheron pénétra dans la forêt avec sa hache, les arbres se dirent : ne nous inquiétons pas, le manche est des nôtres. » | Gérez votre collection de BD en ligne !
Reply

Marsh Posté le 23-02-2005 à 14:26:30    

latruffe a écrit :

Tiens, je connaissais pas le try / catch... c'est 100% php5 ?


en effet, ca me disait rien aussi(normal, je suis pas encore passé à php5  :D )
http://us4.php.net/manual/en/language.exceptions.php

Reply

Marsh Posté le 23-02-2005 à 14:32:22    

lol, je suis passé à php5 mais je conaissais pas non plus.

Reply

Marsh Posté le 23-02-2005 à 16:03:03    

Merci Cerel.
Sinon je suis encore sur PHP4, mais bon, je vois l'idée :jap:

Reply

Marsh Posté le 23-02-2005 à 16:44:30    

Hmmm ?
 
Marche pas en php4 ? Il me semblais que si.
Je suis sur php4 et je les ai utilise l'autre jour...
A moins que ...
 
Ooopsy, je les ai utilise dans du JavaScript :D
Autant pour moi, neanmoins mes exemples restent valables, suffit de les transformer un peu et c'est bon :D
 
[edit]
Vala, j'ai edit mes messages plus haut, afin d'enlever mes "betises". Snif, je les trouvais beaux mes try, catch mwa ... :/
[/edit]


Message édité par cerel le 23-02-2005 à 16:56:15
Reply

Marsh Posté le 23-02-2005 à 17:52:35    

Bah non fallait les laisser :(
 
De toute façon, php5, faudra y passer tot ou tard alors c'est bien d'avoir des exemples :)


---------------
« Lorsque le bûcheron pénétra dans la forêt avec sa hache, les arbres se dirent : ne nous inquiétons pas, le manche est des nôtres. » | Gérez votre collection de BD en ligne !
Reply

Marsh Posté le 23-02-2005 à 17:58:04    

En dehors des grandes nouveautés de php5, j'ai beaucoup de mal à savoir ce qui a pu appraitre.
Pour une fois que j'en découvre une, elle disparait du forum.
Pas cool pour les autres ça. ;)
Et puis comme dit latruffe, il faudra bien y passer tôt ou tard alors mieux vaut se préparer un peu à l'avance ne seraisse que pour savoir ce qu'il est possible de faire. :)

Reply

Marsh Posté le 23-02-2005 à 21:04:38    

cerel a écrit :


2b)(ou 3) Je te conseille de plutot laisser ton if(isset($_SESSIOM... Pour la simple est bonne raison que c'est toi qui "maitrise" la session, alors que le cookie tu le maitrises pas forcement ... Donc en gardant le isset sur la session tu t'evites de mauvaises surprises (il est possible de modifier un cookie sur son navigateur, donc les cookies ne sont pas dignes de confiance).
 
Pour te faciliter la vie, je te conseille de plutot faire soit une page "dedie" au controle du login, soit une fonction qui controle ca.
Comme ca, quand tu veux "proteger" un page il te suffit de faire un truc du genre :

Code :
  1. require_once('control.php');
  2. // ou
  3. require_once('functions_login.php');
  4. control();




 
Bon j'ai bien réfléchis je crois que je vais utiliser cette méthode, mais j'aimerais que vous donniez votre avis avant.
 
 
Sur toutes les pages que je veux protéger, j'insère un require_once "priv.php". Et dans le priv.php je fous le pseudo-code suivant :
 

Code :
  1. session_start();
  2. Si (variable de session inéxistante) {
  3.    Si (variable de cookie éxistante) {
  4.         on récupère $_COOKIE['username'] et $_COOKIE['password']
  5.         on créé les variables $_SESSION associées
  6.         on redirige sur l'index.php
  7.    }
  8.    Sinon {
  9.          include("login.php" );
  10.          // page avec champs de connexion & mdp
  11.          // et qui permettera de créer les variables $_SESSION et le cookie
  12.    }
  13. }


 
 
ça à l'air de marcher :) qu'en pensez vous ?


Message édité par vanilla le 24-02-2005 à 00:08:47
Reply

Marsh Posté le 24-02-2005 à 09:53:53    

J'utilise une methode similaire. :jap:


---------------
« Lorsque le bûcheron pénétra dans la forêt avec sa hache, les arbres se dirent : ne nous inquiétons pas, le manche est des nôtres. » | Gérez votre collection de BD en ligne !
Reply

Marsh Posté le 24-02-2005 à 12:28:56    

Au lieu d'inclure "login", je te conseile de plutot faire une redirection. Sinon ca risque de "casser" ta mise en page.

Reply

Marsh Posté le 24-02-2005 à 13:39:19    

:jap:
 
Je crois que vous avez répondus à mes questions :jap:

Reply

Marsh Posté le 24-02-2005 à 19:06:38    

J'ai encore un problème au niveau de l'authentification avec les cookies déjà existant chez le client.
 
En effet, pour ceux qui aurait pas suivi, je fais le test sur la base de donnée en utilisant les données des cookies que j'ai créé au moment du login.
 
Le problème c'est que ça marche pas avec le $_COOKIE['password'] (mais ça marche avec $_COOKIE['username']  :heink: ). Ma requête SQL qui ressemble grossièrement à  
 
SELECT from blabla  
WHERE username=\''.$_COOKIE['username'].'\'  
AND password=\''.$_COOKIE['password'].'\' ';
 
Quel est-le problème ? Y aurait-il un rapport avec le md5 ? (les mdp dans la table sont hashés en md5, et quand je créé le cookie, je hash le password aussi, donc logiquement ça devrait marcher  :sweat: ).


Message édité par vanilla le 24-02-2005 à 19:07:22
Reply

Marsh Posté le 24-02-2005 à 19:34:02    

y'a bien quelque chose dans ton $_COOKIE['password'] ?
 
C'est différent de ton md5($pass) ?
 
Essaie de faire le check au moment de la création.

Reply

Marsh Posté le 24-02-2005 à 19:38:09    

Fait un "print_r($_COOKIE)", histoire de voir quels cookies existent. Peut-etre que ton cookie password na pas ete bien enregistre chez le client.

Reply

Marsh Posté le 24-02-2005 à 20:25:59    

Ok ça marche, c'est le cookie que je créais qui n'avait pas le ]  bon hash md5 [:kiki]  :jap:  
 
Le seul problème maintenant c'est que mon logout.php ne me déloggue plus ! Puisque j'ai un require_once priv.php sur chaque page, ça me reloggue automatiquement (puisque mes cookies sont jamais détruit, sauf si je le fais manuellement).
 
Comment faire ? (Il me semble qu'on ne peut pas détruire un cookie... ?)
 
edit : apparemment si mais je trouve pas comment faire :o


Message édité par vanilla le 24-02-2005 à 20:36:28
Reply

Marsh Posté le 24-02-2005 à 22:33:11    

sur ton logout, tu fais :
$_COOKIE['username'] = '';
$_COOKIE['password'] ='';
 
+ heure d'expiration dans le passé
 


Message édité par latruffe le 24-02-2005 à 22:35:24
Reply

Marsh Posté le 24-02-2005 à 23:07:08    

latruffe a écrit :

sur ton logout, tu fais :
$_COOKIE['username'] = '';
$_COOKIE['password'] ='';
 
+ heure d'expiration dans le passé


Merci  :jap:  
 
J'ai aussi vu qu'on pouvait le faire en utilisant setcookie (cf manuel :o)

Reply

Marsh Posté le 25-02-2005 à 00:51:01    

latruffe a écrit :

sur ton logout, tu fais :
$_COOKIE['username'] = '';
$_COOKIE['password'] ='';
 
+ heure d'expiration dans le passé


 
Si de toute facon il faut modifier l'heure d'expiration, il faut faire un appel a setcookie. Par consequent on peut eliminer ces deux lignes.
 
Selon le manuel :

Code :
  1. // set the expiration date to one hour ago
  2. setcookie ("TestCookie", "", time() - 3600);
  3. setcookie ("TestCookie", "", time() - 3600, "/~rasmus/", ".example.com", 1);


 
Pour effacer un cookie, faut faire un appel a setcookie, avec le nom du cookie, une value vide, un temps dans le passe. Mais il ne faut pas oublier d'utiliser les meme parametres de "path" "domain" "secure" que lors de la creation de ce dernier.

Reply

Marsh Posté le 17-08-2006 à 19:58:23    

drapal

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed