IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Planning avec zone modifiable


Sujet :

JavaScript

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 54
    Points : 36
    Points
    36
    Par défaut Planning avec zone modifiable
    Bonjour,

    J'ai posté initialement ce message sur une autre section, visiblement la mauvaise ; alors je tente dans la rubrique javascript puisque ma solution serait dans ce langage que je ne connais pas.

    Hier matin, j'ai eu un message URGENT pour un planning en ligne avec la possibilité pour des membres d'une équipe d'insérer des données et pour cela, j'avais un délai de "4 heures" mouahah, ils sont mignons....

    Monter le tableau ne m'a pas posé de problème, ni faire la zone d'administration pour l'admin. Mais le truc nouveau pour moi, était qu'une case pouvait être éditable par un membre et qu'une fois son info entrée, cela s'enregistrait dans la BDD.

    J'ai essayé tout ce que j'ai pu trouvé sur le web : contenteditable, innerHTML, XMLHttpRequest... sans succès.

    J'ai commencé avec des codes trouvés sur le web. Mais à force d'essais... nul.

    J'avais trouvé un lien et une proposition intéressante. C'est ce que j'ai tenté en dernier lieu... échec. Je ne connais rien à Javascript et des choses m'échappent ; je ne suis plus certaine non plus de la logique de mon code... je crois que j'ai fait une belle tambouille.

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    <?php
    include('connexion_sql.php');
    ?>
     
     
    <?php include("haut.php"); ?>
        <header>
            <h1>PLANNING</h1>
        </header>
     
     
     
     
    <section id="centre">
        <div id="corps"><a id="ancrecontenu"></a>
     
            <table id="tableau">
                <caption>Planning de</caption>
     
                <thead>
                    <tr>
                        <th class="cacher" scope="col" rowspan="2">ID_PC</th>
                        <th scope="col" rowspan="2">Da</th>
                        <th scope="col" rowspan="2">Po</th>
                        <th scope="col" colspan="2">H</th>
                        <th scope="col" rowspan="2">Ve</th>
                        <th scope="col" rowspan="2">CHE</th>
                        <th scope="col" rowspan="2">CHA</th>
                        <th scope="col" colspan="2">S</th>
                    </tr>
                    <tr>
                        <th scope="col" class="nogras">h_d</th>
                        <th scope="col" class="nogras">h_f</th>
     
                        <th scope="col" class="nogras">s_1</th>
                        <th scope="col" class="nogras">s_2</th>
                    </tr>            
                </thead>
     
                <tfoot></tfoot>
     
                <tbody>
                    <?php
                    $req = $bdd->query('SELECT id_pc, da, po, h_d, h_f, ve, che, cha, s_1, s_2
                                        FROM planning
                                        ORDER BY date')
                                        or die(print_r($bdd->errorInfo()));
     
                    define ('TAB', '     ') ;
                    while ($donnees = $req->fetch()) {
                        extract ($donnees);
     
                        $id_pc=$donnees["id_pc"];
                        $date=$donnees["da"];
                        $poste=$donnees["po"];
                        $heure_d=$donnees["h_d"];
                        $heure_f=$donnees["h_f"];
                        $vehicule=$donnees["ve"];
                        $chef=$donnees["che"];
                        $chauffeur=$donnees["cha"];
                        $secouriste_1=$donnees["s_1"];
                        $secouriste_2=$donnees["s_2"];
     
     
     
                        echo PHP_EOL . '<tr>';
                        echo PHP_EOL . TAB . '<td class="cacher">' .$id_pc. '</td>';
                        echo PHP_EOL . TAB . '<td scope="row">' .$da. '</td>';
                        echo PHP_EOL . TAB . '<td class="nowrap">' .stripslashes($po). '</td>';
                        echo PHP_EOL . TAB . '<td>' .$h_d. '</td>';
                        echo PHP_EOL . TAB . '<td>' .$h_f. '</td>';
                        echo PHP_EOL . TAB . '<td>' .$ve. '</td>';
                        echo PHP_EOL . TAB . '<td>' .stripslashes($che). '</td>';
                        echo PHP_EOL . TAB . '<td contenteditable="true">' .stripslashes($cha). '</td>';
                        echo PHP_EOL . TAB . '<td contenteditable="true">' .stripslashes($s_1). '</td>';
                        echo PHP_EOL . TAB . '<td contenteditable="true">' .stripslashes($s_2). '</td>';
                        echo PHP_EOL . TAB . "<td><button onclick='modifier(this.parentElement)'>ok</button></td>" ;
                        echo PHP_EOL . '</tr>';
                    }
                    ?>
                    <script type="text/javascript">
                    <!--
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
                    function modifier(X) {
                        array = X.getElementsByTagName('TD');
                        xhr = new XMLHttpRequest() ;
                        xhr.open("POST", "maj.php", false) ;
                        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded") ;
                        chaine  = 'id_pc=' + array[1].innerHTML
                                + '&da='  + array[2].innerHTML
                                + '&po=' + array[3].innerHTML
                                + '&h_d='   + array[4].innerHTML
                                + '&h_f='  + array[5].innerHTML
                                + '&ve='  + array[6].innerHTML
                                + '&che='  + array[7].innerHTML
                                + '&cha='  + array[8].innerHTML
                                + '&s_1='  + array[9].innerHTML
                                + '&s_2='  + array[10].innerHTML;
                        xhr.send(chaine);
                    }
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
                    -->
                    </script>
     
                    <?php
                    extract($_POST) ;
                    $req2 = $bdd->query ("UPDATE planning
                        SET da='$da', po='$po', h_d='$h_d', h_f='$h_f', ve='$ve', che='$che', cha='$cha', s_1='$s_1', s_2='$s_2' WHERE id_pc='$id_pc'") or die(print_r($bdd->errorInfo()));
     
                    ?>
                </tbody>
            </table>
     
        </div>
    </section>
     
     
    <footer id="copyright"><?php include("copyright.php"); ?></footer>
     
    <?php include("bas.php"); ?>

    Ce matin, j'ai trouvé cela : https://www.webucator.com/tutorial/l...e.cfm#tutorial mais je ne connais pas AJAX .

    Il n'y a rien de pire que de chercher à "bidouiller" quand tu ne maîtrises pas certains langages, la perte de temps et d'énergie est énorme

    Quelqu'un peut/veut-il me dépatouiller svp ? C'est pour une bonne cause

    Merci

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Citation Envoyé par Marie08 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xhr.open("POST", "maj.php", false) ;

    Dis-moi où tu as trouvé ça, que j’aille taper sur les doigts de l’auteur.
    En mettant false ta requête devient synchrone. Ça bloque le fil d’exécution de l’interface. Ça retire tout intérêt à Ajax. Le A de Ajax signifie asynchrone… Les gens qui conseillent de faire de l’Ajax synchrone n’ont tout simplement rien compris, et sont responsables de la prolifération d’une mauvaise pratique.

    Bref. Parlons de ton problème. Ta requête semble bien écrite, à un détail près : tu fais commencer ton tableau à 1, alors qu’il doit commencer à 0. Du coup tout est décalé, tes données n’ont pas les bons noms.

    Il te manque un retour d’information côté client. Pour être en mesure de voir si la requête a réussi, tu dois lui ajouter un gestionnaire d’évènement load, avant d’appeler send :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    xhr.addEventListener('load', function () {
      console.log('La requête a réussi. Réponse du serveur :');
      console.log(this.responseText);
    });
    Ouvre la console de ton navigateur avec la touche F12 pour voir les messages. Dans cette fonction que je viens d’écrire, tu pourras rajouter du code pour signaler à l’utilisateur que les données ont bien été enregistrées, en utilisant simplement un alert ou en insérant du HTML dans la page.




    Pour le moment ta page maj.php ne fait pas la différence entre une requête de mise à jour des données et une simple requête d’affichage de la page. Idéalement il faudrait que tu aies un script PHP différent pour gérer la requête de mise à jour. Quoiqu’il en soit, ton script souffre d’un énorme problème de sécurité : extract($_POST);. En utilisant extract, tu crées des variables sans aucun contrôle. En lui passant $_POST, tu permets à l’utilisateur d’injecter des variables dans ton script, sans les contrôler. C’est le même problème qu’avec register_globals. Un utilisateur un peu bidouilleur peut regarder ton script client et facilement modifier les requêtes Ajax. A priori il ne connaît pas le contenu de ton script PHP, mais tu lui laisses de la marge pour tenter des trucs, et par principe de précaution, il vaut mieux éviter ça.

    À la place, extrais les données une par une à la main, ça te permet de contrôler leur valeur (par exemple si la donnée est censée être un nombre, tu peux utiliser int_val), et également vérifier qu’il n’en manque pas. Bon réflexe : toujours contrôler l’existence d’une donnée POST ou GET avec isset. C’est le moyen le plus efficace d’éviter les avertissements undefined index (car on est d’accord, ignorer ou supprimer les avertissements c’est toujours une mauvaise idée ).

    Même remarque avec extract($donnees), même si c’est moins grave dans ce cas : les données viennent de la base, elles sont censées être « propres » car c’est toi qui les as insérées (a priori). Dans tous les cas, ça fait double emploi avec les $id_pc = $donnees['id_pc']; etc. que tu as écrits juste après. Mon conseil : n’utilise jamais extract. Il n’est pas vraiment utile (c’est juste du confort) et crée trop d’incertitude.

    Autre énorme faille : ta requête SQL n’est pas protégée ! L’utilisateur peut tenter une injection SQL, et au final c’est toi qui seras responsable du vol ou de la destruction des données de la base. Pour éviter ça, utilise PDO::quote ou PDO::prepare.

    Prévois de renvoyer une réponse pour signaler au client (ta requête Ajax) que l’insertion s’est bien ou mal passée. Actuellement tu as un or die(print_r($bdd->errorInfo())), un peu trop bavard car il révèle la structure de ta requête SQL et donc de ta table. Ce sont des informations très utiles pour les pirates. Envoie simplement un « l’insertion a échoué » ou quelque chose comme ça, et inscris les informations détaillées dans un journal qui reste sur serveur. Basiquement, tu peux faire ça avec error_log.

    Une dernière chose : puisque ton code JS utilise innerHTML, ton serveur va potentiellement recevoir des bouts de code HTML, non désamorcés. En l’état, ils peuvent se retrouver dans ta base, et retourner côté client. Ça donne la possibilité à l’utilisateur d’envoyer des balises <script> ou <iframe>, etc. Tu vois venir le malaise ? C’est une vulnérabilité aux attaques XSS.
    Pour éviter ça tu dois utiliser strip_tags ou htmlspecialchars.

    En tout tu avais donc trois types de failles dans ton application. Bienvenue dans la jungle cruelle du Web ! Rassure-toi, si tu fais les choses étape par étape, tu vas y arriver. Et si tu n’y arrives pas, j’ai des bouts de code pour t’aider.

    Allez au boulot, c’est URGENT, n’oublie pas tu n’as que quatre heures
    Sérieusement si tu dis à tes boss que tu as corrigé trois failles de sécurité, tu pourrais demander une augmentation…

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 54
    Points : 36
    Points
    36
    Par défaut
    Wouhaaa....

    Avec une telle réponse, je n'ai pas le droit d'abandonner ! Pour tout dire, je leur ai donné un os à ronger le temps de me retourner Et j'avais fait ça : http://www.developpez.net/forums/d16...e/#post8744197 et je pensais m'en tirer avec sécurisant l'ensemble et en créant un accès restreint et sécurisé.

    Mais bon... raté. Ta réponse me donne des pistes de recherche que je vais exploiter.

    Dis-moi où tu as trouvé ça, que j’aille taper sur les doigts de l’auteur.
    Nan ! c'est mal la délation ! (même si c'est très tendance...)

    Quoiqu’il en soit, ton script souffre d’un énorme problème de sécurité : extract($_POST);
    C'est effectivement ce que m'avait déconseiller Sabotage sur l'autre topic ; avec tes explications, je comprends maintenant pourquoi.

    Actuellement tu as un or die(print_r($bdd->errorInfo())), un peu trop bavard car il révèle la structure de ta requête SQL et donc de ta table.
    Ah c'est ballot ça, parce que je mets ça dans tous les sites que je développe... (visiblement, suis toujours une zéro du SDZ )

    Sérieusement si tu dis à tes boss que tu as corrigé trois failles de sécurité, tu pourrais demander une augmentation…
    Pfff... même pas. C'est pire qu'un boss, c'est ma descendance... Et je leur ai toujours appris à ne rien lâcher tant qu'ils n'obtenaient pas ce qu'ils voulaient. Oui... je suis dans la mouise Quant à l'augmentation, je fais toujours bénévolement, pour des pro/bénévoles au secours des citoyens

    Allez, au boulot. Peut-être qu'avec le neurone qu'il me reste, je devrais apprendre Ajax ?


Discussions similaires

  1. [PHP 5.0] Planning avec zone modifiable
    Par Marie08 dans le forum Langage
    Réponses: 4
    Dernier message: 17/09/2016, 13h24
  2. Difficulté avec Zone de Liste modifiable
    Par YOP33 dans le forum IHM
    Réponses: 2
    Dernier message: 17/01/2008, 19h24
  3. Réponses: 13
    Dernier message: 08/02/2007, 17h05
  4. Sous formulaire avec zone de liste modifiable
    Par Krakotte dans le forum IHM
    Réponses: 7
    Dernier message: 20/01/2006, 10h21
  5. probleme avec zone liste modifiable en mode continu
    Par hellosct1 dans le forum Access
    Réponses: 3
    Dernier message: 16/11/2005, 13h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo