Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1250 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Diverses questions sur l'art de programmer correctement

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Diverses questions sur l'art de programmer correctement

n°1820760
garfunk71
Posté le 02-12-2008 à 16:22:09  profilanswer
 

Bonjour à tous,

 

J'ai récemment recommencé à coder un site Web pour mon petit plaisir personnel (je suis un joueur de MMO, j'ai donc créé un site en rapport avec ce jeu).
Seulement, vu que ce petit projet prend de l'ampleur, et que j'ai peut-être en vue de le distribuer (gratuitement bien sûr, c'est pas pour ce que ça représente...), j'ai plus ou moins décidé de coder un truc CORRECT.
Et c'est là que, cher public, tu interviens !!
J'ai besoin de vos lumières concernant plusieurs points de mon code, pour être sûr d'avoir: un truc stable, un truc sécurisé un minimum, et enfin évolutif (pas codé avec les pieds).
J'ai donc besoin de vos lumières.
Voilà comment je suis parti :

  • Base de données de comptes, avec un id, un login, un mot de passe (stocké en md5), et un champ admin.
  • Le premier inscrit est administrateur non modifiable (il n'apparait pas dans la liste des gens à qui un administrateur peut retirer le droit).
  • Le (ou les) administrateur(s) peu(ven)t visiter une page spéciale (dont le lien n'apparaît que lorsqu'on est admin).
  • J'utilise le système de session de PHP. En mémoire(ie dans le tableau $_SESSION), à la connexion, sont stockées : l'id, le login (pour ne pas avoir à refaire des requêtes lorsque j'en ai besoin), et le statut d'admin (0 ou 1).
  • J'ai codé mon site avec des jolies div, et une feuille CSS. Pour construire ma page, j'ai découpé celle-ci en différentes parties, chaque contenu de div (header, barre de connexion, menu, footer) est appelé via un include. Seul le header est sous forme de fonction pour me permettre de modifier le titre de la page (j'appelle le header via affich_header('Accueil') qui renvoie toute la partie avec 'Accueil' en title par exemple pour la page d'accueil).
  • Pour valider mes formulaires, j'utilise une page php dédiée (exemple, une page change_password.php) qui vérifie qu'on est connecté, fais les vérifications d'usage (par exemple ici, que les deux mots de passe sont bien identiques, etc), insère dans la base de données puis renvoie sur la page de compte.php avec un header:Location.


J'aimerais avoir vos avis sur ces méthodes, si il y a des choses à changer, etc...
Par exemple, je ne fais presque pas de vérification sur mes contenus de formulaires (par exemple pour le module de news, je fais juste un nl2br() et un addslashes() sur le contenu), et skeye m'a conseillé mysql_real_escape_string(), fonction sur laquelle je vais me pencher).
Si vous avez d'autres suggestions, d'autres conseils, je suis tout ouïe.
Je peux plus détailler si besoin (extrait de code, etc...).

 

Merci d'avance !

 

PS : mon précédent post : http://forum.hardware.fr/hfr/Progr [...] 9591_1.htm


Message édité par garfunk71 le 02-12-2008 à 16:22:38
mood
Publicité
Posté le 02-12-2008 à 16:22:09  profilanswer
 

n°1820762
flo850
moi je
Posté le 02-12-2008 à 16:29:02  profilanswer
 

ca me semble pas mal  
 
j'ajouterai  

  • htmlentites sur l'affiche de tout texte extrait de la base de données
  • mysql_real_escape_string sur toutes les variables qui doivent apparaitrent dans une requete ( ou des requetes preparées )  
  • une validation en js des formulaire ( attention ,ça ne dispence pas de la validation en php )


---------------

n°1820763
Marty_McFl​y
Nan hé ho, d'accord?
Posté le 02-12-2008 à 16:29:33  profilanswer
 

Citation :

Le (ou les) administrateur(s) peu(ven)t visiter une page spéciale (dont le lien n'apparaît que lorsqu'on est admin).
 


Sur cette page, est ce que tu vérifies que l'utilisateur qui se connecte est effectivement un admin? Parce que ce n'est pas parce que le lien n'est pas visible sur le site qu'il n'est pas 'atteignable'.
 

Citation :

je ne fais presque pas de vérification sur mes contenus de formulaires
 


Est ce que tu connais les requetes préparées? Si non, je te conseille de te renseigner sur le sujet, ça pourrait etre pas mal :p
 

Citation :

Je peux plus détailler si besoin (extrait de code, etc...).
 


Url du site?


---------------
arg(z) = pi /2 donc z = i, moi je prends pas
n°1820765
garfunk71
Posté le 02-12-2008 à 16:38:43  profilanswer
 

Oui, je vérifie que le $_SESSION['admin'] est bien à 1 sinon je dégage le boulzor sur l'index.php...
Les requêtes préparées je ne vois pas ce que c'est en fait...
Je vais regarder.
url : www.garfunk.fr (je bosse dessus, tout n'est pas dispo, vous pouvez vous inscrire pour visualiser la partie modification de mot de passe) et les personnages (mais vous en aurez pas :p ).
Ah oui, une partie du site se connectera via curl au ladder de Dofus pour récupérer les personnages et leurs caractéristiques (et pas de olol Dofus je joue presque plus -_- ).
htmlentities => quoi qu'est-ce ?
Confirmation en JS : stadir, vérifier qu'il y a pas de code html ou SQL dans mes champs de texte ? J'ai déjà essayé de limiter au maximum la taille des champs (via maxlength).
Merci de vos retours !
 
PS : une petite question me turlupine : les données du tableau $_SESSION sont inaccessibles par un tiers ?

n°1820773
kao98
...
Posté le 02-12-2008 à 16:49:09  profilanswer
 

Un petit truc aussi que je fais à chaque fois : si l'utilisateur est un administrateur, en cas d'accès à une page d'admin, lui demander son mot de passe. Enfin, pas à chaque accès aux page d'admin ! Mais à chaque nouvelle session.
 
Edit : t'as vu ça : http://forum.hardware.fr/hfr/Progr [...] 7565_1.htm ?


Message édité par kao98 le 02-12-2008 à 16:52:02

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
n°1820779
garfunk71
Posté le 02-12-2008 à 16:57:51  profilanswer
 

Oui, j'ai vu, mais je suis a peu près capable de régler mes erreurs, ce que je voudrais, c'est savoir si par exemple faire une page dédiée aux traitements des informations est une bonne idée, ou si il faut plutôt renvoyer sur la même page (celle-ci devant alors détecter si il y a des données en $_POST pour les traiter, ce qui je trouve alourdit vraiment la page), ce genre de choses...
Pour lui redemander le mot de passe, comment je dois faire ? Puisque la session est déjà créée, comment je peux faire pour lui demander son mot de passe ?
Je rajoute un paramètre dans le $_SESSION qui est à 0, ce qui force la demande du mdp admin lors de l'ouverture de la page admin.php, et qui passe à 1 ensuite ?
Ou faut-il créer un cookie spécifique ?
Merci de tes remarques !

 

PS : je viens de voir les requêtes préparées. Ce genre de chose est utile lors de traitements longs et répétés, par exemple afficher tous les personnages d'un compte (une simple boucle, qui contient une autre boucle pour les métiers de chaque personnage) ?
Mais dans les autres cas, en quoi c'est plus intéressant et plus sécurisé ? Par le fait que ça ne prend qu'un paramètre qui a déjà été défini lors de la préparation ?


Message édité par garfunk71 le 02-12-2008 à 17:00:14
n°1820792
kao98
...
Posté le 02-12-2008 à 17:11:43  profilanswer
 

Pour l'histoire du mdp, c'est ça : lors de l'initialisation de la session, une données qui est, par exemple, à 0, et qui n'est pas mise à jour à la lecture du cookie.
 
Et lorsque l'on souhaite une page d'administration, si cette var est à 0, alors on demande le MDP admin. S'il est correct, c'est var passe à 1, ce qui évite de demander à nouveau le MDP. Mais bien sûr, cette données n'est pas sauvegardée dans le cookie !


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
n°1820805
Profil sup​primé
Posté le 02-12-2008 à 17:18:02  answer
 

Citation :


INSERT INTO accounts (`id` ,`login` ,`password` ,`comment` ,`lastupdate` ,`last`) VALUES ('' , '\\\'simple\\\' \\\"double\\\"', 'bdb8c008fa551ba75f8481963f2201da', 'Aucun commentaire.', '32', `02/12 à 17:12`);Unknown column '02/12 Ã  17:12' in 'field list'


Je vois donc un triple addslashes()
Je ne vois pas ce que 'id' vient faire la, comment non plus.
Je ne vois pas pourquoi tu n'utlises pas les NOW() pour les dates de modifications

n°1820808
Profil sup​primé
Posté le 02-12-2008 à 17:20:09  answer
 

Pour connecte.php ca ne va pas du tout.
Tu dois traiter ton formulaire dans la même page et afficher les erreurs de validations dedans si il y en a. Et si c'est ok pour la validation, ensuite tu rediriges.

n°1820811
garfunk71
Posté le 02-12-2008 à 17:22:05  profilanswer
 

En parlant de cookie...
Je stocke dedans le login ainsi que le mot de passe en md5, séparé par un "|" (je les récupère via explode() ).
Dois-je y stocker autre chose ? Sur l'ancienne version du site, je stockais déjà uniquement ces deux valeurs. Or, lorsque j'ai donné le log à un ami pour déploiement sur son site de guilde perso, sur lequel je me suis inscrit avec les mêmes informations (identifiant et mot de passe), je me retrouvais connecté sur les deux et déconnecté sur les deux en même temps !! (ce qui est logique vu que les infos sont identiques dans le cookie)...
Je pensais y mettre le domaine, il est récupérable via un un petit script du genre http://www.phpsources.org/scripts388-PHP.htm ?
Ou autre chose ? L'ip c'est peut-être pas une bonne idée vu qu'elle change souvent...

mood
Publicité
Posté le 02-12-2008 à 17:22:05  profilanswer
 

n°1820829
garfunk71
Posté le 02-12-2008 à 17:34:00  profilanswer
 

Comment est un résidu de l'ancienne version qui risque de me servir plus tard. Je le laisse de côté pour ne pas avoir a remodifier mes requêtes et ma base de données :) (Après tout, c'est vrai que je pourrais ne pas l'inclure dans la requête :( ).
En fait cette requête est l'une des rares que j'ai copié-collé de PHPMyAdmin, c'est pour ça qu'il y a les ` pour les noms des champs. Je peux supprimer id, de toute façon il est en auto-increment.
Pour connect.php, je ne comprends pas. Tu veux dire que le formulaire de connexion doit renvoyer sur lui-même pour vérifier les informations, et si c'est correct renvoyer sur la page d'index ?
C'est de ça dont je parlais par exemple. Est-il plus judicieux d'utiliser des pages externes ou doit-on faire les traitements sur la même page ? Apparemment il faut envoyer le formulaire sur la page elle-même, et détecter si des informations ont été fournies en $_POST pour les traiter...
Donc, renvoyer les erreur en $_GET n'est pas une bonne idée ? :sweat:

 

Quant au triple addslashes, je ne comprends pas  :??:
Voici le code de la page register2.php, celle qui s'occupe de traiter les infos de la page register (je suppose que tu as provoqué cette erreur en insérant des guillemets dans le nom d'utilisateur lors d'une inscription):

Code :
  1. if ($pass == $pass2) {
  2.  //les pass sont identiques
  3.   $pass = md5($pass);
  4.   $sql = "INSERT INTO ".$mysql_prefix."accounts (`id` ,`login` ,`password` ,`comment` ,`lastupdate` ,`last`) VALUES ('' , '".addslashes($login)."', '".$pass."', 'Aucun commentaire.', '32', `".date("d/m \à H:i" )."`);";
  5.   //exécution de la requête SQL
  6.   $requete = @mysql_query($sql) or die($sql.mysql_error());


(Il ne s'agit que de la partie intéressante, je te passe les vérifications : champs login rempli, mdp aussi, login qui n'existe pas dans la bdd).
Le 32 pour le lastupdate a été mis en dur mais contient normalement le jour sous forme décimale (j'ai besoin d'autoriser ou non la mise à jour toutes les 24H, ça m'a paru une bonne idée, simple et efficace). Ce champ est modifié lorsqu'on met à jour, pour permettre la mise à jour dès l'inscription, j'ai mis 32 (aucun mois n'a 32 jours rassurez-moi  :sol: ).

Message cité 1 fois
Message édité par garfunk71 le 02-12-2008 à 17:36:33
n°1820923
Profil sup​primé
Posté le 02-12-2008 à 19:29:02  answer
 

Bon alors,
 

Citation :


En parlant de cookie...
Je stocke dedans le login ainsi que le mot de passe en md5, séparé par un "|" (je les récupère via explode() ).


J'espère quand même que tu ne stockes pas les mdp dans les cookies ????
Même si c'est hashé ce n'est pas secure du tout.  
Tu dois uniquement socker l'id de session et c'est tout.
 
Pour les slashes, tu vas passer par pdo et préparer tes requêtes et le problème sera résolu.
 
Pour les formulaire tu dois les traiter dans la même page. Ca semble évident.
Si ta validation est failed, tu vas faire quoi ? passer tes messages d'erreurs ET tes valeurs en Get ? et tu retraites comment après ?
Non gère tout dans la même page bien sur.
 
Pour tes dates de modifs, mets un NOW() et basta ça te fera un soucis de moins à gérer maintenant et surtout quand tu reviendras dans 6 mois tu ne passeras pas 1h à te demander ce que c'est que ce truc.

n°1820934
NewsletTux
<Insérez ici votre vie />
Posté le 02-12-2008 à 20:22:23  profilanswer
 

si tu dois faire entrer du monde dans la prog, il y a qq conseils qui n'ont pas encore été donnés mais qui peuvent servir ...
En tous cas ce que tu as dit me semble un bon début également.
 
1/ un code lisible, indenté. rien de pire que de chercher une accolade ou une parenthèse fermante ...
 
2/ un code commenté, et efficacement. commenter "if ($a < 10) par " // si $a inférieur à 10", on s'en fout. Mais pourquoi $a, pourquoi <, pourquoi 10 ?. Le commentire doit bien entendu précéder le code qu'il commente.
 
3/ choisir des noms de classes/méthodes/fonctions/variables explicites. $temp = nul. $somme_a_payer = mieux.
 
4/ bien récupérer tes variables, si tu attends un entier, un décimal, un string, t'assurer du type de ce que tu attends. Au besoin, transtyper (en sachant que ça "force" le type, donc permet de se prémunir de certaines choses, mais ça n'est pas non plus la solution miracle, puisqu'il n'y a pas de retour sur l'erreur pour l'utilisateur).
 
5/ pas de MdP en clair, ni en session (apparemment c'est bon pour toi). Pas de SELECT * (peut être gourmand en ressources inutilement).
 
6/ dans l'idéal, tout faire en anglais, si tu prévois de l'international.


---------------
NewsletTux - outil de mailing list en PHP MySQL
n°1820943
garfunk71
Posté le 02-12-2008 à 20:48:16  profilanswer
 

Merci de vos retours (surtout corten, même si tu es un peu vif, je débute je te rappelle :/ je me doute bien que je fais des erreurs, je suis là pour ne pas les renouveler aussi ;) ).
Je stocke le mpd hashé en md5 dans le cookie si. Je ne pensais pas que md5 était autant une passoire...
Ce cookie ne sert que pour la connexion automatique, celle qui évite de re-rentrer les infos de connexion à chaque visite. Tu as une meilleure méthode, plus secure ?
Je viens d'aller voir pour pdo, et je n'ai pas compris le principe : c'est une interface, mais elle consiste en quoi exactement ? Pourquoi utiliser ces méthodes de connexion et de récupération d'informations plutôt que les commandes mysql habituelles ? (c'est pas un piège, je me pose réellement la question...).
Pour le now, c'est en effet une très bonne idée, je ne connaissais pas du tout le champ timestamp de mysql et les fonctionnalités qu'il procure (surtout les calculs d'intervalles entre deux dates, fantastique ça !!!).
Je vais étudier le problème.

 

Pour NewsletTux, j'essaye déjà d'appliquer tout ça (je ne fais pas de programmation objet, je ne vois pas en quoi ça serait un gain pour ce que je veux faire, surtout que je gère beaucoup moins bien que la programmation classique :/).
Je commente aussi mon code, de la manière que j'estime être la plus efficace. Pour les variables en anglais, j'essaye dans la mesure du possible mais il arrive que je manque d'imagination :p

 

Encore merci


Message édité par garfunk71 le 02-12-2008 à 21:25:30
n°1820962
Profil sup​primé
Posté le 02-12-2008 à 21:21:13  answer
 

je ne suis pas sec, j'explique [:prodigy]  
 
bon alors,
si c'est pour rester connecté durant la visite, c'est en session que ça se passe.
Si c'est pour etre encore connecté de visite en visite faut un cookie. La dedans tu mets tout sauf le login ou le mot de passe. Une bonne idée est de générer une clé unique (genre une 20aine de caractères) pour chaque utilisateur. A l'identification, tu checkes le login/mdp, si c'est ok tu fais un setcookie avec la clé primaire utilisateur et la clé unique. T'auras juste un ptit select à faire quand il reviendra.
Et pour ne pas faire ce check à chaque page qu'il visite, tu lui ouvres une session au début.
 
Pour pdo bah voir doc. Les requêtes préparées sont le seul moyen d'échapper correctement tes données quand tu les mets en db.  
Par exemple, un addslashes() ça va bien pour les données avec un ', mais il se passe quoi si on envoie de l'hexa ? ... Donc vu qu'on ne sait pas tout prévoir, on laisse les gens qui font ça toute leur journée s'en occuper.
 
Bon la t'en a pour ta soirée  
A+  [:raoul_volfoni]

n°1820970
garfunk71
Posté le 02-12-2008 à 21:39:34  profilanswer
 

Ca fait beaucoup d'un coup mais bon...
Quand on est motivé...
Concernant la session, le cookie est créé a la connexion. Il contient le login et le mdp.
Ensuite, quand l'utilisateur REVIENT sur le site, je regarde si un cookie existe, si oui j'extrais les valeurs, si elles correspondent à un couple, je récupères, testes dans la base de données, et si c'est good, je crées la session avec les informations !!
Si le cookie n'existe pas (ou a été détruit via le logout.php), je crée la session à l'identification.
A savoir que le cookie est créé suivant le choix de l'utilisateur (une case à cocher sous le formulaire de connexion, tu as du la remarquer :p ).

 

Pour rester connecté, j'utilise en effet la session, pas de souci. Le cookie n'est là que pour reconnaître qqun, point barre.
Concernant la clé primaire dont tu parles, elle serait stockée dans la bdd au même titre que le login ? Ou alors tu fais un hash du login suivant un algorithme perso, hash que tu dois retrouver dans le cookie ?
Pour utiliser les requêtes préparées (que je compte utiliser, je vois bien l'utilité du truc, surtout niveau sécurité et injection SQL), je dois forcément utiliser pdo ?
En tout cas, même si j'ai un peu l'impression d'être la dernière des buses en programmation PHP, ça fait plaisir d'avoir quelques lignes directrices pour coder correctement ;)


Message édité par garfunk71 le 02-12-2008 à 21:47:32
n°1820976
NewsletTux
&lt;Insérez ici votre vie /&gt;
Posté le 02-12-2008 à 22:10:37  profilanswer
 

mes remarques sont pour la prog en général, pas spécialement "orientée objet".


---------------
NewsletTux - outil de mailing list en PHP MySQL
n°1821102
Profil sup​primé
Posté le 03-12-2008 à 10:30:53  answer
 

Pour ton cookie c'est bien mais tu ne dois PAS stocker le couple login/mot de passe. Une bonne idée est de stocker un couple id/id de ton choix, c'est beaucoup plus difficile à s'en servir que login/mdp
Pour la clé primaire, tu en as une, c'est id dans ta table accounts


Message édité par Profil supprimé le 03-12-2008 à 10:31:49
n°1821516
garfunk71
Posté le 03-12-2008 à 17:31:27  profilanswer
 

Edit : sans objet finalement. PDO permet aussi de fetcher sous forme de tableau associatif via PDO::FETCH_ASSOC (je m'entêtais à utiliser le fetch en objet que je ne maîtrise pas du tout :/ ).


Message édité par garfunk71 le 03-12-2008 à 17:44:22
n°1821599
FlorentG
Posté le 03-12-2008 à 19:32:50  profilanswer
 

garfunk71 a écrit :

Quant au triple addslashes, je ne comprends pas  :??:


Utilise mysq_real_escape_string au lieu de addslashes, ça sécurise mieux en prenant en compte les paramètres d'encoding de la base.

 

Et attention, suivant la config de php, les tableaux $_GET, $_POST, etc. peuvent être déjà addslashisés, ce qui peut faire chier grave. Le mieux est de les nettoyer au tout début s'il le faut, genre :

Code :
  1. function arrayStripSlashes($array)
  2. {
  3.    if(!empty($array)) {
  4.  
  5.        foreach($array as $key => $value) {
  6.  
  7.            $sKey = stripslashes($key);
  8.  
  9.            $array[$sKey] =
  10.                is_array($value) ? arrayStripSlashes($value) :
  11.                stripslashes($value);
  12.  
  13.            if($key != $sKey) {
  14.                unset($array[$key]);
  15.            }
  16.        }
  17.    }
  18.    return $array;
  19. }
  20.  
  21.  
  22.    $_SERVER  = arrayStripSlashes($_SERVER);
  23.    $_REQUEST = arrayStripSlashes($_REQUEST);
  24.    $_GET     = arrayStripSlashes($_GET);
  25.    $_POST    = arrayStripSlashes($_POST);
  26.    $_COOKIE  = arrayStripSlashes($_COOKIE);
  27. }


PHP, I love it


Message édité par FlorentG le 03-12-2008 à 19:33:26

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Diverses questions sur l'art de programmer correctement

 

Sujets relatifs
Questions sur le synchronizedquestions pour cré site internet
[PHP] timeout 0 dans le php.ini, quelques questionsSimplification de mon code et 2 questions
[C] Cherche quelqu'un pour me programmer qqchose : payé.Outils pour programmer en langage Fortran
[Webpart WSS] Questions sur les WebpartsQuestions sur l'allocation memoire
programmer un emploi de temps scolaire en programmation apr contrainte[BAT/VBS] Plusieurs questions
Plus de sujets relatifs à : Diverses questions sur l'art de programmer correctement


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR