Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Débutant] Message de bienvenue - connexion

Sujet résolu
    10 décembre 2018 à 0:09:35

    Bonjour à tous,

    Je suis en train de créer un espace membre pour mon site. Pour vous expliquer mon problème : Lors de la connexion du membre je souhaite le rediriger sur l'index en lui indiquant un message de bienvenue (snackbar).

    L’utilisateur se situe donc sur la page connexion => il se connecte => une fois connecté il atterrit sur la page index => un message de bienvenue s’affiche pour lui ! 

    Cela parait simple, mais je souhaite que ce message s'affiche qu'une seule fois et que les données ne transitent pas par l'URL.

    Je pensais lors de l'inscription faire transiter une valeur de "1" (pour activer le message) via un formulaire masqué (hidden) mais je n'y arrive pas... Avez vous des idées ?

    Je vous remercie d'avance pour votre aide :)

    <?php
    
    try
    {
    	$bdd = new PDO('mysql:host=localhost;dbname=probe;charset=utf8', 'root', '');
    }
    catch(Exception $e)
    {
      die('Erreur : '.$e->getMessage());
    }
    
    if (!empty($_POST)) {
       	$mail = htmlspecialchars($_POST['email_utilisateur_connexion']);
       	$mdp = htmlspecialchars($_POST['mdp_utilisateur_connexion']);
    
       	if ($mail != "" AND $mdp != "") {
            $maillength = strlen($mail);
            $mdplength = strlen($mdp);
    
            if ($maillength <= 50 AND $mdplength <= 50) {
                $mail_hache = sha1($mail);
                $req = $bdd->prepare('SELECT id, pass, membreconfirme, pseudo FROM membres WHERE email = :email');
                $req->execute(array(
                'email' => $mail_hache));
                $resultat = $req->fetch();
    
                $isPasswordCorrect = password_verify($mdp, $resultat['pass']);
    
                if (!$resultat)
                  {
                    $erreur ="L'email ou le mot de passe est incorrect !";
                  } else {
    
                        if ($isPasswordCorrect) {
                          $membreconfirme = $resultat['membreconfirme'];
    
                          if ($membreconfirme == 1) {
                            session_start();
                            $_SESSION['id'] = $resultat['id'];
                            $_SESSION['pseudo'] = $resultat['pseudo']; //C'est ici que je redirige vers l'index
                            header("Location: /probe/index.php");
                            exit();
    
                          } else {
                            $erreur = "Vous n'avez pas confirmé votre compte !";
                          }
                        }
                        else {
                            $erreur ="L'email ou le mot de passe est incorrect !";
                        }
                      }
              }else {
                $erreur = "L'email ou le mot de passe dépasse le nombre de caractère autorisé !";
              }
    
          } else {
       		$erreur = "Tous les champs doivent être complétés !";
       	}
    }
    ?>



    -
    Edité par clemsK7 10 décembre 2018 à 7:19:24

    • Partager sur Facebook
    • Partager sur Twitter
      10 décembre 2018 à 8:45:48

      Juste avant la ligne 41 ajoute simplement un $_SESSION['message_bienvenu'] = 1;. Ensuite sur index.php si $_SESSION['message_bienvenu'] est définit et == 1, tu affiches le message et tu fais un unset($_SESSION['message_bienvenu']).

      L'index de $_SESSION n'étant plus définit la condition n'est plus respecter et ainsi le message n'est affiché qu'une seule fois.

      • Partager sur Facebook
      • Partager sur Twitter
        10 décembre 2018 à 10:05:08

        Ton utilisation de htmlspecialchars est incorrecte relit la doc sinon tu risques de te faire fouetter ici :-° 

        Sur quoi te bases-tu pour vérifier la longueur d'une adresse email ? Dans la norme une adresse peut atteindre jusqu'à 320 caractères, ici tu la limites à 50 caractères.

        • Partager sur Facebook
        • Partager sur Twitter
          10 décembre 2018 à 11:38:01

          Merci RPG Book, c’est vraiment que c’était assez simple :D C’est la méthode idéal

          xoxotf Je vais regarder la documentation, mais pourtant cette méthode fonctionne non ? C’est pour se protéger des injections de code

          Je me suis basé sur cela car je ne la connaissais pas :) Mais mais est-ce pertinent d’accepter des mail de 300 caractères ?

          Je vous remercie de votre aide :)

          • Partager sur Facebook
          • Partager sur Twitter
            10 décembre 2018 à 11:48:14

            Comment sais-tu ce que fais htmlspecialchars si tu n'a pas lu la doc ? Toujours vérifier par sois même :euh: 

            Je pense que c'est pertinent dans le sens ou un utilisateur avec un long mail ne va pas s'amuser à recréer un mail juste parce que ton site n'accepte pas son adresse. Il faut se mettre à la place de l'utilisateur constamment.

            • Partager sur Facebook
            • Partager sur Twitter
              10 décembre 2018 à 12:41:35

              @clemsK7 : Je ne connais pas ton niveau de programmation mais ce que @xoxotf te dis est vrai. Tu devrais lire la documentation de chaque fonction PHP que tu utilises pour être sûr de ce que tu fais. En l’occurrence, htmlspecialchars() est une fonction qui va simplement convertir les éléments liés au langage HTML dans leur codage ASCII (Exemple : < et > deviendront &gt; et &;lt;). Bien que htmlspecialchars() vient remplacer les caractères ' et " (et encore, je me trompe peut être), ça ne protège pas forcément des injections. Ou en tout cas, ce n'est clairement pas la méthode à utiliser.

              Pour sécuriser pleinement tes données contre l'injection SQL, la meilleure solution à mon sens reste les requêtes préparées.

              Source : http://php.net/manual/fr/pdo.prepared-statements.php

              Un autre bon moyen de sécuriser tes données est en prévention (front via JS/back en PHP) en analysant les données reçues. Spécialement lorsque tu es sensé faire un traitement dessus AVANT insertion. Par exemple, via l'usage de is_numeric(), isset(), gettype() & empty(). Sécuriser contre l'injection SQL mais ne pas vérifier les données avant traitement ne provoquera pas une faille de sécurité, mais potentiellement un résultat logique différent de celui escompter. C'est d'autant plus vrai quant on vient modifier le DOM ou envoyer des requêtes POST pré-préparer en dehors du contexte de ton navigateur pour tenter de pirater ton site.

              Sache cependant qu'il existe plusieurs façons de sécuriser son site et qu'il n'y a pas qu'une seule solution de viable.

              Petite note : Ce qui m'a le plus choqué, moi, c'est pourquoi tu récupères l'adresse mail pour ensuite vérifier le mot de passe ? Ne serait-il pas plus facile de rechercher un résultat fonction du mail et du mot de passe directement pour ensuite voir s'il y a une occurrence ? (Via mysqli_result::$num_rows ?) S'il y a 0, c'est que le mot de passe est incorrect, s'il y en a une, c'est que le mot de passe est bon. Après, c'est toi qui organise ton code comme tu veux. Ta méthode fonctionne aussi ! :ange:

              • Partager sur Facebook
              • Partager sur Twitter
                10 décembre 2018 à 12:53:06

                 xoxotf a écrit:

                Comment sais-tu ce que fais htmlspecialchars si tu n'a pas lu la doc ? Toujours vérifier par sois même :euh: 

                Je pense que c'est pertinent dans le sens ou un utilisateur avec un long mail ne va pas s'amuser à recréer un mail juste parce que ton site n'accepte pas son adresse. Il faut se mettre à la place de l'utilisateur constamment.

                J’ai trouvé ceci dans la documentation, ce que tu veux me dire c’est de fait htmlspecialchars de mes inputs ? Pas des variables post ?

                <?php
                $new 
                htmlspecialchars("<a href='test'>Test</a>"ENT_QUOTES);
                echo 
                $new// &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
                ?>



                • Partager sur Facebook
                • Partager sur Twitter
                  10 décembre 2018 à 13:36:20

                  Pour faire simple, tu anesthésies toutes données rentrant en BDD avec des requêtes préparées comme renseigner plus haut, puis quand tu veux afficher ces données, et uniquement à l'affichage, tu utilises htmlspecialchars, pour éviter les attaques du type XSS et autres.

                  -
                  Edité par xoxotf 10 décembre 2018 à 13:36:50

                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 décembre 2018 à 20:14:10

                    RPGBookOnline a écrit:

                    @clemsK7 : Je ne connais pas ton niveau de programmation mais ce que @xoxotf te dis est vrai. Tu devrais lire la documentation de chaque fonction PHP que tu utilises pour être sûr de ce que tu fais. En l’occurrence, htmlspecialchars() est une fonction qui va simplement convertir les éléments liés au langage HTML dans leur codage ASCII (Exemple : < et > deviendront &gt; et &;lt;). Bien que htmlspecialchars() vient remplacer les caractères ' et " (et encore, je me trompe peut être), ça ne protège pas forcément des injections. Ou en tout cas, ce n'est clairement pas la méthode à utiliser.

                    Pour sécuriser pleinement tes données contre l'injection SQL, la meilleure solution à mon sens reste les requêtes préparées.

                    Source : http://php.net/manual/fr/pdo.prepared-statements.php

                    Un autre bon moyen de sécuriser tes données est en prévention (front via JS/back en PHP) en analysant les données reçues. Spécialement lorsque tu es sensé faire un traitement dessus AVANT insertion. Par exemple, via l'usage de is_numeric(), isset(), gettype() & empty(). Sécuriser contre l'injection SQL mais ne pas vérifier les données avant traitement ne provoquera pas une faille de sécurité, mais potentiellement un résultat logique différent de celui escompter. C'est d'autant plus vrai quant on vient modifier le DOM ou envoyer des requêtes POST pré-préparer en dehors du contexte de ton navigateur pour tenter de pirater ton site.

                    Sache cependant qu'il existe plusieurs façons de sécuriser son site et qu'il n'y a pas qu'une seule solution de viable.

                    Petite note : Ce qui m'a le plus choqué, moi, c'est pourquoi tu récupères l'adresse mail pour ensuite vérifier le mot de passe ? Ne serait-il pas plus facile de rechercher un résultat fonction du mail et du mot de passe directement pour ensuite voir s'il y a une occurrence ? (Via mysqli_result::$num_rows ?) S'il y a 0, c'est que le mot de passe est incorrect, s'il y en a une, c'est que le mot de passe est bon. Après, c'est toi qui organise ton code comme tu veux. Ta méthode fonctionne aussi ! :ange:


                    - Hmmm, conversation très intéressante ! Je suis débutant en php et html, il y'a tous juste 1 mois je ne savais rien faire :D Je n'avais pas regarder la documentation php pour htmlspecialchars, mais j'y veillerais à l'avenir.

                    Alors attention moi je parle des injections de code via une faille XSS, pour les injections SQL je fais des requêtes préparée dans mon code. Voilà l'article d'openclassroom que j'ai utilisé pour htmlspecialchars :

                    https://openclassrooms.com/fr/courses/2091901-protegez-vous-efficacement-contre-les-failles-web/2680167-la-faille-xss

                    Comme vous pouvez le voir il utilise cette fonction directement pour un $_POST

                    - Si j'ai bien compris pour sécuriser mes données je doit faire des vérifications des entrées de l'utilisateur à l'aide de ces fonctions : s_numeric() isset() gettype() et empty() ? Afin de voir si les champs ne sont pas vide, correspondent à mes attentes ect j'imagine

                    -Je suis tout à fait d'accord avec toi, j'y ai pensé. Mais j'utilise la fonction password_hash pour mes mots de passes, ce qui fait qu'en mettant le même mot de passe à mouliner dans cette fonction je n'aurais jamais le même résultats (elle me permet aussi de gérer les salts). Je suis obligé d'utiliser la fonction password_verify qui me renvoie un boolean. Donc ça ne fonctionnera pas avec une simple requête. Enfin je pense..

                    -
                    Edité par clemsK7 10 décembre 2018 à 20:14:42

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 décembre 2018 à 0:20:19

                      Attention il le fait sur un post car ce dernier est affiché avec un echo mais pas sauvegarder en base de données. Le soucis de faire htmlspecialchars pour une insertion en base c'est que outre le fait que ça ne sécurise pas la bdd (même si tu la compris je le rappel pour d'autre qui lirai). Mais en plus de ça, cela pollue tes données de caractères inutiles et peut même être relou pour un utilisateur.

                      Prenons l'exemple d'une inscription ou le pseudo doit faire max 10 caractères. Si le mec entre <pseudo> (avec les chevrons ) et bien en base sont pseudo sera &lt;pseudo&gt;

                      Cela veut dire que son pseudo au mieux sera refusé si tu fais le check de la longueur avant l'insertion et au pire tronqués en base si tu as mis que la taille max est de 10 (ce qui est bien en soit vu que ça permet de ne pas avoir plus de poids que nécessaire). Et le jour ou tu veux faire une recherche il faudra aussi faire un htmlspecielchars.

                      Enfin voilà des petits exemples :)

                      -
                      Edité par quenti77 11 décembre 2018 à 0:21:14

                      • Partager sur Facebook
                      • Partager sur Twitter
                        11 décembre 2018 à 1:23:01

                        Hello, 

                        je profite d'un bref passage éclaire ici pour rajouter mon grain de sel à cette conversation :

                        Ma méthode préférée pour identifier un membre

                        Personnellement, je travaille en deux fois :

                        • Je ne récupère que le mot de passe et l'id correspondant à un login / mail donné
                        • Je test ce mot de passé récupéré de la BDD avec celui fourni par l'utilisateur
                        • Si c'est OK, et seulement si c'est OK, je vais puiser mes infos supplémentaires en BDD, avec l'id obtenue auparavant comme clause WHERE. Sinon, ça dégage.

                        Ceci à l'avantage de ne pas surcharger le serveur avec trop de données à récupérer à chaque fois que quelqu'un tente un mot de passe. Cependant, je précise que j'utilise les fonctions password_hash et password_verify pour ça.

                        Ma méthode pour les messages dits "flash"

                        Un message flash est un message qui apparaît en général une fois lors de la navigation, et qui disparaît au changement de page ou sur une actualisation de page.

                        Pour ce faire, je passe par les sessions, avec une petite fonction qui m'affiche mes messages, puis les supprime des sessions pour la suite. Une tonne de tutos te donneront la méthode sur le net.

                        Pour ton cas, je serais passé par un champs en BDD du genre "first_login" de type datetime, null par défaut. A la création du compte, ce champ est laissé vide. A la connexion, on test s'il est toujours nul. Si oui, on y inscrit la date et l'heure actuelle puis on affiche un message, sinon, on ne fait rien.

                        Utile pour des petits comptages aussi, par exemple connaitre le nombre de compte créés mais jamais utilisés ... (champ encore à null)

                        Sécuriser au mieux ses requêtes avec PDO

                        Je vois que tu te sers de requêtes préparées, ce qui est déjà bien en terme de sécurisation. A condition d'en tirer pleinement partie.

                        L'idéal est d'y aller à grands coups de bindValue(). Je m'explique : Mis à par le fait que tu indiques une clé et une valeur par laquelle la remplacer dans ta requête, tu peux également lui préciser un type attendu. Exemple, $stmt -> bindValue(':foo', $bar, PDO::PARAM_INT); n'acceptera qu'un entier.

                        Ainsi, tu peux préciser, colonne par colonne, quelle type de donnée est attendu. A toi de gérer ensuite les erreurs possible avec la gestion intégrée à PDO (à condition de bien configurer la connexion)

                        Je te laisse consulter la doc des paramètres de PDO ici.

                        Je vois que tu t'investis pas mal dans la programmation, et si je peux me permettre, voici quelques conseils niveau BDD :

                        Définis bien tes tables à l'avance, avec des noms de table et de colonnes clairs. Rien de plus chiant que de trouver une requête SELECT a,b,c as R, d, e FROM t_bd WHERE g=12, crois moi ^^

                        Définis bien tes champs et les index. Ne pas forcément prendre exemple sur les tutos, mais fouiller les docs. Par exemple, un champ INT n'a pas besoin d''avoir une taille de 11, 5 suffit. Par contre, un PRIMARY KEY est souvent du type unsigned, ce qui te permet de "doubler" la valeur max possible pour ton champ ...

                        Utilises si possibles plusieurs tables avec des jointures pour limiter la redondance de données. Exemple : tu as un blog, des articles et des catégories. Il est préférable de lister les catégories d'un côté, et les articles de l'autre, en les liant avec des identifiants numérique (souvent via une troisième table). Cela permet de lister tes articles selon X ou Y catégorie de manière plus simple et plus rapide que sur une recherche texte. C'est aussi plus évolutif par la suite ...

                        Si tu as besoin d'autres conseils, n'hésite pas à revenir sur le forum, certains d'entre nous bravent encore sa lente disparition pour y apporter nos connaissances ^^

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Kwo:re / topic OC | Aidez les autres, indiquez un sujet résolu ! | Vous êtes bloqué ? Suivez le guide ! | N'aide pas par MP
                          11 décembre 2018 à 9:41:35

                          Je vous remercie tous pour vos réponses, elles vont beaucoup m'apporter pour mon site ! Et avant tous @Ealon, ton message va beaucoup m'aider

                          C'est quand même génial les forums :) Dommage que celui d'Openclassroom tende à disparaitre, partit pris que je ne comprend pas d'ailleurs...

                          • Partager sur Facebook
                          • Partager sur Twitter
                            12 décembre 2018 à 23:02:29

                            Hello,

                            Attention aussi à dissocier les failles XSS temporaires des permanentes (permanentes = enregistrés dans la BDD). Effectivement, je pensais que tu parlais des injections SQL. On ne parle pas d'injection XSS, mais bien de faille XSS. Une faille XSS, c'est tout simplement.. dans le cas d'une faille XSS permanente, imagines un livre d'or dans lequel tu peux mettre des commentaires. Les commentaires sont affichés dans des DIV. Si l'utilisateur rentre en message "</div>", ça va briser la DIV et afficher n'importe quoi.

                            C'est mineur, bien entendu, mais l'utilisateur pourrait aussi être amener à faire appel à des IFrame ou même aux propriétés Z-INDEX / POSITION:ABSOLUTE pour provoquer un "site under", qui en gros consiste à afficher un autre site à la place du livre d'or.

                            D'un point de vu beaucoup plus grave, il existe plusieurs méthodes via les failles XSS pour faire des dégâts vraiment important, à la fois pour ton site, mais aussi pour tes internautes.

                            Pour te résumer, avec une requête bien préparée pour l'insertion en base de donnée, il n'est pas nécessaire d'utiliser htmlspecialchars() (surtout que, au risque de répéter ce qui a déjà été dis plein de fois, ça ne sécurise pas ton insertion !). Par contre, il sera PRIMORDIAL ensuite de l'utiliser à l'affichage et de ne pas l'oublier.

                            Tiens, voici par exemple un code "écraser une mouche avec un maillet" qui te permettrait d'obtenir quoi qu'il arrive tout le temps du contenu sécurisé :

                            function SecureShow($rss) {
                            	if(mysqli_num_rows($rss) > 0) {
                            		$return = array();
                            		
                            		while($d = mysqli_fetch_assoc($rss)) {
                            			$arr = array();
                            			
                            			foreach($d as $key => $value) {
                            				array_push($arr[$key], htmlspecialchars($value));
                            			}
                            			
                            			array_push($return, $arr);
                            		}
                            		
                            		return $return;
                            	} else {
                            		return false;
                            	}
                            }

                            Prends en argument une ressource SQL (mysqli_query()) et retourne un ARRAY a parcourir de la façon suivante (au lieu de while($x = mysqli_fetch_assoc()) :

                            $return = SecureShow(mysqli_query($link, "xxxx"));
                            
                            foreach($return as $key => $value) {
                            	// Traitement
                            }

                            A tester, je n'ai pas de serveur sous la main, j'ai du le faire de tête. :ange:

                            EDIT : A savoir aussi, n'utilises jamais mysqli_fetch_array(). C'est une grossière erreur, car cela retourne les résultats en double (numérique et associatif). Dans 99% des cas, la seule chose qui va t'intéresser, c'est les clés associatives, et non numériques. Quelques exemples utiles :

                            Clé numérique : $query[1] == "clemsK7";

                            Clé associative : $query['user'] == "clemsK7";

                            > mysqli_fetch_array() -> $query[1] == $query['user'], doublon.

                            > mysqli_fetch_assoc() -> $query[1] == UNDEFINED && $query['user'] == "clemsK7".

                            > mysqli_fetch_row() -> $query[1] == "clemsK7" && $query['user'] == UNDEFINED.

                            -
                            Edité par RPGBookOnline 12 décembre 2018 à 23:07:22

                            • Partager sur Facebook
                            • Partager sur Twitter

                            [Débutant] Message de bienvenue - connexion

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown