Espace membre, sécurisé le mot de passe....

Eléphant du PHP | 440 Messages

03 janv. 2008, 17:41

Bonjour à tous,

Je voudrait réaliser une espace membre pour le site intranet de ma boite, voici mon code:
<?php session_start(); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html lang="fr">
<head>
<title> login</title>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
<style type="text/css" title="mes_styles" media="all">
<!--
#login {
border: medium solid #FF9900;
border-collapse: collapse;
position: absolute;
	top: 20px;
	left: 350px;
}
#ok{
font-family: Georgia, "Times New Roman", Times, serif;
color:#FF9900;
margin-top: 120px;
margin-left: 350px;
}

-->

</style>
<body>

<?php
If(isset($_POST['validation']))

{
If(isset($_POST['login']))	$login=$_POST['login'];
else $login = "";

If(isset($_POST['mdp']))	$mdp=$_POST['mdp'];
else $mdp = "";

If (empty($login) OR empty($mdp))
	{
	echo 'login ou mot de passe incorrecte ou manquant 1';
	
	}
	else
	{
$server="*******";
$user="****";
$pass="*****";
$db="pdr";
mysql_connect($server,$user,$pass) or die('erreur de connexion');
mysql_select_db($db) or die ('impossible de se connecter a la base'); 

$requete = "SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= '$login';";
$query = mysql_query($requete) or die('Erreur SQL !'.$query.'<br>'.mysql_error()); 
		//echo $mdp;
		echo '<br>';
$data= mysql_fetch_assoc($query);
		//echo 'le mot de passe est'.$data['mdp_user'].'ok';
		echo '<br>';
		if($data['mdp_user']!= $mdp)
		{
		echo 'login ou mot de passe incorrecte ou manquant 2';
		}
		else
		{
		//session_start();
		$_SESSION['login'] = $login;
		echo $_SESSION['login'];
		echo '<div id="ok" >Vous etes bien logue, bienvenue '.$data['prenom_user'].' '.$data['nom_user'].'.<br>';
		echo "<script type='text/javascript'>document.location=\"acceuil.php\";</script>";
		echo '<FORM ACTION="acceuil.php" > <INPUT TYPE="SUBMIT" VALUE="Par ici !"> </FORM></div>';
		}
	}
}
else
{
?>
<form action="<?php echo($_SERVER['PHP_SELF']); ?>" method='post'>
<table id="login">
  <tr>
    <td>Login :</td>
    <td><input type="text" name="login" maxlength="250"></td>
  </tr>
  <tr>
    <td>Password</td>
    <td><input type="password"name="mdp" maxlength="10"></td>
  </tr>
  <tr>
    <td colspan="2" align="center"><input type="submit" name="validation" id="validation" value="log in"></td>
  </tr>
</table>
</form>



<?php
}

?>

	
</body>
</html>
Est qu'au niveau de mon code il y a des erreurs ? (la page fonctionne mais je préfère demander)

Au niveau des mots de passe, je voudrait les sécurisé soit au niveau de ma base ou bien sur le site.
Quel méthode me conseillez vous (je chercherais comment l'appliquer) (pas trop dure non plus je débute :D )
$_SESSION['login'] = $login;
echo $_SESSION['login'];
echo '<div id="ok" >Vous etes bien logue, bienvenue '.$data['prenom_user'].' '.$data['nom_user'].'.<br>';
echo "<script type='text/javascript'>document.location=\"acceuil.php\";</script>";
echo '<FORM ACTION="acceuil.php" > <INPUT TYPE="SUBMIT" VALUE="Par ici !"> </FORM></div>';
A ce niveau si j'ai fait une re-direction en javascript mais est-il possible de lui attribuer un temps avant de l'exécuter? A-t-il une meilleur méthode (ou est-il préférable d'utiliser) en php ?

Pour sécuriser les autres pages (de l'espace membre ) j'ai ceci comme code:
<?php session_start(); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html lang="fr">
<head>
<title> login</title>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
<?php
echo $_SESSION['login'];

if(!isset($_SESSION['login'])) {
	echo $_SESSION['login'];
  echo 'Vous n\'êtes pas autoris´ à acceder à cette zone';
  echo '<br>';
  include('login.php');
  exit;
}
else
{
echo $_SESSION['login'];
echo 'Bienvenue sur l\'espace restreint ';
}
?> 
Est ce que c'est suffisant ou pas ?

Merci d'avance pour votre aide
Bonne et heureuse année.

guigui69

Invité
Invité n'ayant pas de compte PHPfrance

03 janv. 2008, 18:44

ca m'a l'air correct bien qu'un peu bordélique :p

attention toutefois à ta requete SQL qui peut être victime de malveillance


remplace :

Code : Tout sélectionner

$requete = "SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= '$login';";
par :

Code : Tout sélectionner

"SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= 'mysql_real_escape_string($login)";
pour ce qui est de la protection de tes mdp, tu peux les encrypter très facilement dans ta bd avec des fonctions de hashage md5.

enfin, concernant les redirections : c'est le mal !! mais ca c'est mon avis personnel


[/code]

Invité
Invité n'ayant pas de compte PHPfrance

03 janv. 2008, 18:57

heu ouais jme suis chié sur le code fais plutot comme ca :

Code : Tout sélectionner

$login = mysql_real_escape_string($login); // ou $login = addslashes($login); $requete = SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= '$login'";
ca marchera mieux :p

Eléphanteau du PHP | 30 Messages

03 janv. 2008, 21:44

Je suis en train de faire aussi un Espace Membre.

Je fais comme à dit l'Invité j'utilise md5.

C'est simple a faire! Lorsqu'un utilisateur s'inscrit, tu ajoutes à la place du mot de passe brut, la fonction md5 (c a d: md5(lemdp);) ce qui le cryptera.

Va voir le manuel PHP pour plus de renseignement! :)

Eléphant du PHP | 440 Messages

04 janv. 2008, 10:51

Merci pour votre aide,

Au sujet des mots de passe, en fais c'est moi qui créé les login et mot de passe (pour les personnes de mon entreprise). Donc pour que les mots passe soit codé Je devrait agir a quel niveau php ou mysql ?

Si le mot de passe est crypté sur ma base je devrait comparé les 2 valeurs MD5, c'est bien ca?
Au niveau de ma base comment mettre mon champ mot passe en md5?

Merci d'avance

guigui69

------------------------
MAJ

J'ai modifier dans ma base mysql le champ mot passe crypté en MD5, et dans ma page web je verifie dans ma page le mot passe que je vient de taper (puis convertit en md5) si il est identique à celui dans ma base.

Code : Tout sélectionner

<?php session_start(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="fr"> <head> <title> login</title> <meta http-equiv="content-type" content="text/html;charset=iso-8859-1" /> <style type="text/css" title="mes_styles" media="all"> <!-- #login { border: medium solid #FF9900; border-collapse: collapse; position: absolute; top: 20px; left: 350px; } #ok{ font-family: Georgia, "Times New Roman", Times, serif; color:#FF9900; margin-top: 120px; margin-left: 350px; } --> </style> <body> <?php If(isset($_POST['validation'])) { If(isset($_POST['login'])) $login=$_POST['login']; else $login = ""; If(isset($_POST['mdp'])) $mdp=$_POST['mdp']; else $mdp = ""; If (empty($login) OR empty($mdp)) { echo 'login ou mot de passe incorrecte ou manquant 1'; } else { $server="******"; $user="*******"; $pass="******"; $db="pdr"; mysql_connect($server,$user,$pass) or die('erreur de connexion'); mysql_select_db($db) or die ('impossible de se connecter a la base'); $login = mysql_real_escape_string($login); // ou $login = addslashes($login); $requete = "SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= '$login'"; //$requete = "SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= '$login';"; $query = mysql_query($requete) or die('Erreur SQL !'.$query.'<br>'.mysql_error()); //echo $mdp; echo '<br>'; $data= mysql_fetch_assoc($query); //echo 'le mot de passe est'.$data['mdp_user'].'ok'; echo '<br>'; $tmp = md5($data['mdp_user']); echo $tmp; echo '<br>'; if($data['mdp_user']!= md5($mdp)) { echo 'login ou mot de passe incorrecte ou manquant 2'; } else { //session_start(); $_SESSION['login'] = $login; echo $_SESSION['login']; echo '<div id="ok" >Vous etes bien logue, bienvenue '.$data['prenom_user'].' '.$data['nom_user'].'.<br>'; echo "<script type='text/javascript'>document.location=\"acceuil.php\";</script>"; echo '<FORM ACTION="acceuil.php" > <INPUT TYPE="SUBMIT" VALUE="Par ici !"> </FORM></div>'; } } } else { ?> <form action="<?php echo($_SERVER['PHP_SELF']); ?>" method='post'> <table id="login"> <tr> <td>Login :</td> <td><input type="text" name="login" maxlength="250"></td> </tr> <tr> <td>Password</td> <td><input type="password"name="mdp" maxlength="10"></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" name="validation" id="validation" value="log in"></td> </tr> </table> </form> <?php } ?> </body> </html>
Est qu'il faut mettre au chose en place pour sécurisé l'espace membre ?
attention toutefois à ta requete SQL qui peut être victime de malveillance
Qu'entend tu part ça? j'ai rajouter la ligne que tu ma dit.

C'est fonction permet de garder intacte la valeur si elle comporte une apostrophe ou autre, non ?

Merci

guigui69

Invité
Invité n'ayant pas de compte PHPfrance

07 janv. 2008, 15:54

oui voilà, la fonction mysql_real_escape string va échapper tous les caractères spéciaux pour éviter qu'ils soient interprétés par le moteur sql de ta base de données. Dans le cas contraire, un utilisateur mal intentionné peut injecter du code SQL dans ta requête (très dangereux).

Autre chose, ta requete

Code : Tout sélectionner

$requete = "SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= '$login'";
Elle peut renvoyer des valeurs vides si le login n'est pas existant.
Admettons que je rentre un login qui n'existe pas avec un mot de passe vide :

$data['mdp_user'] == ($mdp) renverra donc vrai (à verifier tout de meme)

Je te conseille donc de procéder comme ceci :

Code : Tout sélectionner

$mdp = md5($mdp); $requete = "SELECT login_user, mdp_user, nom_user, prenom_user FROM user WHERE login_user= '$login' and mdp_user='$mdp'"; $resultat = mysql_query($requete); if (mysql_num_rows($resultat) == 1) { //ok } else { //pas ok }
après cette modif ca devrait etre bon ;)


un peu de lecture :
http://fr.php.net/mysql_real_escape_string
http://www.phpsecure.info/v2/article/phpmysql.php

ViPHP
AB
ViPHP | 5818 Messages

07 janv. 2008, 18:31

Typiquement, et si tu veux pouvoir transposer ton code sur n'importe quel serveur, voici une variante (en supposant que les mots de passes soient cryptés en md5 dans ta bdd) :
function stripgpc($value) {
if(get_magic_quotes_gpc()) $value = stripslashes($value);
return $value;
}

$mdp = isset($_POST['mot_de_passe']) ? md5(stripgpc($_POST['mot_de_passe'])) : '';
$login = isset($_POST['identifiant']) ? stripgpc($_POST['identifiant']) : '';

if(!empty($mdp) && !empty($login)) 
{
$selection = sprintf("SELECT COUNT(*) as compte FROM inscription WHERE mot_de_passe ='%s' AND identifiant ='%s'",
mysql_real_escape_string($mdp),
mysql_real_escape_string($login)); 

$query = mysql_query($selection) or die(mysql_error());
$totalReponse = mysql_fetch_assoc($query);

if ($totalReponse['compte'] == 1 ) {
echo 'membre identifié';
}
else 
{
echo 'membre non identifié';
} 
}

Eléphant du PHP | 440 Messages

08 janv. 2008, 16:35

Merci, pour vos réponses, j'ai vérifier mon code:

Si l'utilisateur rentre ni login ni mot de passe ou seulement l'un des 2 il lui renverra

Code : Tout sélectionner

If (empty($login) OR empty($mdp)) { echo 'login ou mot de passe incorrecte ou manquant 1'; } else { .....
Est-ce bon quand même ou est-il préférable de passé par vos code précédemment cité AB et invité?

Je vais regarder les codes comme vous m'avez donnés et voir si je les comprends :(

Merci d'avance

guigiu69

=================================

MAJ

Je n'arrive pas a comprend cette partie:

Code : Tout sélectionner

function stripgpc($value) { if(get_magic_quotes_gpc()) $value = stripslashes($value); return $value; } $mdp = isset($_POST['mot_de_passe']) ? md5(stripgpc($_POST['mot_de_passe'])) : ''; $login = isset($_POST['identifiant']) ? stripgpc($_POST['identifiant']) : '';

Mammouth du PHP | 965 Messages

08 janv. 2008, 17:06

http://fr3.php.net/manual/fr/function.g ... es-gpc.php

Retourne la configuration actuelle de l'option magic_quotes_gpc

en fait il existe une fonction magiq quote qu'il faut desactiver sur ton server mais parfois tu ne peux pas alors il faut passer par une fonction simple.

En fait il prends la valeur regarde si les magic quote sont mise sur ton server, ensuite il ajoute des addslashes le cas échéant, c'est une simple fonction pour eviter qu'il ne fasse une requete avec des noms style "les '\\\apostrophes".

Eléphant du PHP | 440 Messages

09 janv. 2008, 10:29

Merci pour ta réponse, mais c'est pas plutôt il supprime les slashes (stripslashes) ?

guigui69

ViPHP
AB
ViPHP | 5818 Messages

09 janv. 2008, 21:29

Merci pour ta réponse, mais c'est pas plutôt il supprime les slashes (stripslashes) ?

guigui69
Oui, sa langue à fourché :wink:

C'est bien ce que réalise cette ligne :
Si get_magic_quotes_gpc() est activé, le serveur va mettre des slashes (si nécessaire) dans toutes les variables $_GET, $_POST, $_COOKIE (d'où l'appellation gpc). Pour les supprimer uniquement si get_magic_quotes_gpc() est activé et afin d'obtenir la valeur originale de la variable ont utilise donc la fonction stripslashes();
if(get_magic_quotes_gpc()) $value = stripslashes($value);
J'ai donc créer la petite fonction stripgpc (j'aurai pu l'appeler 'carambar' ) qui contient cette ligne et retourne la valeur de la variable envoyée à la fonction, débarrassée des éventuels slashes au cas où get_magic..gpc() est activé
function stripgpc($value) {
if(get_magic_quotes_gpc()) $value = stripslashes($value);
return $value;
} 
Pour traiter chaque variable avec ma fonction stripgpc(), je fais donc :
$login = isset($_POST['identifiant']) ? stripgpc($_POST['identifiant']) : ''; 
//md5 uniquement si les mots de passe sont codés en md5 dans la base de donnée
$mdp = isset($_POST['mot_de_passe']) ? md5(stripgpc($_POST['mot_de_passe'])) : '';
Cette manière de faire à l'avantage de donner les bons résultats sur n'importe quel serveur, quelque soit sa configuration.


C'est ensuite la fonction mysql_real_escape_string() qui servira pour protéger les variables dans la requête.

ViPHP
AB
ViPHP | 5818 Messages

09 janv. 2008, 23:31

Et puis ton code est mal organisé, faut éviter de mettre du code php dans ton code html quand ce n'est pas nécessaire. En reprenant les éléments de ton premier post ça devrait ressembler à quelque chose comme :
<?php session_start();

if(isset($_POST['validation']))

{ 

   function stripgpc($value) {
   if(get_magic_quotes_gpc()) $value = stripslashes($value);
   return $value;
   }

   $mdp = isset($_POST['mdp']) ? md5(stripgpc($_POST['mdp'])) : '';
   $login = isset($_POST['login']) ? stripgpc($_POST['login']) : '';

   if(!empty($mdp) && !empty($login)) 
      {

      $server="*******";
      $user="****";
      $pass="*****";
      $db="pdr";
      mysql_connect($server,$user,$pass) or die('erreur de connexion');
      mysql_select_db($db) or die ('impossible de se connecter a la base');

      $selection = sprintf("SELECT COUNT(*) as compte FROM user WHERE mdp_user ='%s' AND login_user ='%s'",
      mysql_real_escape_string($mdp),
      mysql_real_escape_string($login)); 

      $query = mysql_query($selection) or die(mysql_error());
      $totalReponse = mysql_fetch_assoc($query); 

       if ($totalReponse['compte'] == 1 ) 
          {
          $_SESSION['login'] = $login;
          header("Location: accueil.php"); exit();
          }
          else
          {
          $message = 'login ou mot de passe incorrect';
           }
       }
       else 
      {
       $message = 'login ou mot de passe manquant';
       }  
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Document sans nom</title>

<style type="text/css" title="mes_styles" media="all">
<!--
#login {
border: medium solid #FF9900;
border-collapse: collapse;
position: absolute;
    top: 20px;
    left: 350px;
}
#ok{
font-family: Georgia, "Times New Roman", Times, serif;
color:#FF9900;
margin-top: 120px;
margin-left: 350px;
}

-->

</style>
</head>
<body> 
<div>
<form action="<?php echo($_SERVER['PHP_SELF']); ?>" method='post'>
<table id="login">
  <tr>
    <td>Login :</td>
    <td><input type="text" name="login" maxlength="250"></td>
  </tr>
  <tr>
    <td>Password</td>
    <td><input type="password"name="mdp" maxlength="10"></td>
  </tr>
  <tr>
    <td colspan="2" align="center"><input type="submit" name="validation" id="validation" value="log in"></td>
  </tr>
</table>
</form> 
</div>
<div><?php if (isset($message)) echo $message ?></div>
</body>
</html>
Voilà quelque chose de plus "propre". Encore que tu aurais pu te passer de tableau et utiliser simplement des balises div ou p pour faire ton formulaire :wink:
Modifié en dernier par AB le 13 janv. 2008, 21:46, modifié 2 fois.

Eléphant du PHP | 440 Messages

10 janv. 2008, 12:14

Merci je regarde ça, mais il y une partie du code que je ne comprend pas

Code : Tout sélectionner

header(sprintf("Location: %s", acceuil.php)); exit();
le header envoir une en tete html.

Mais le sprintf ainsi que %s je ne comprend pas a quoi ca sert ainsi que leur fonction. (j'ai regarder la signification de sprintf mais je la comprend pas :(

Location c'est pour re-dirigé vers une autre page.

Je ne voit pas pourquoi il y a exit a la fin.

Merci d'avance pour votre aide

guigui69

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 janv. 2008, 12:29

S'il y a quelque chose qui te gène, il suffit de le virer et tu verras qu'elle ne te gènera plus ;)

Plus sérieusement, la fonction sprintf() généralement utiliser à tort et à travers, a en gros pour but de permettre de construire une chaine et de la formater en y intégrant les valeurs spécifiées...

En gros ici
sprintf("Location: %s", "accueil.php")
il va remplacer le premier '%s' qui symbolise une chaine, par le premier argument qui suit dans la fonction, et qui devrait en toute logique être une chaine (manque d'ailleurs les quotes sur la tienne)

Le résultat étant la chaine
"Location: accueil.php"
Merci sprintf(), c'était vraiment très interessant.... ;)

En gros tout ce qu'il te faut pour la redirection c'est :
header("Location: accueil.php"); 
exit(); 
Quant au exit(), il faut savoir que malgré l'envoi du header() au navigateur et la redirection qui va suivre, php va continuer d'exécuter le script... Si par exemple tu modifies une variable de session après le header(), celle-ci sera modifié sur la prochaine page en dépit de la redirection. L'exit() permet d'interrompre le script et éviter que php n'aille exécuter la suite du code.
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

ViPHP
AB
ViPHP | 5818 Messages

10 janv. 2008, 21:23

Bon voilà, pour ceux qui prendrait le code ci-dessus comme modèle, il est viré le sprintf :)

On pourrait aussi le virer pour la requête mais je ne trouve pas l'écriture plus facile. A la lecture on y gagnerait cependant quand il y a beaucoup de variables.