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 !";
}
}
?>
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.
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.
Comment sais-tu ce que fais htmlspecialchars si tu n'a pas lu la doc ? Toujours vérifier par sois même
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.
@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 > 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.
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 !
Comment sais-tu ce que fais htmlspecialchars si tu n'a pas lu la doc ? Toujours vérifier par sois même
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 ?
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.
@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 > 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.
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 !
- 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 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 :
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..
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 <pseudo>
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.
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 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
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é :
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()) :
A tester, je n'ai pas de serveur sous la main, j'ai du le faire de tête.
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 :
- Edité par RPGBookOnline 12 décembre 2018 à 23:07:22
[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.
My website : Mon serveur discord, Se demerder tout seul, Faille XSS et SQL