Page 1 sur 1

Problème pour créer un espace membre

Posté : 11 août 2006, 10:05
par Chakra Spirit
Bonjour, :D

Je suis tout nouveau par ici.
Je viens vous voir car je débute en php et j'éprouve quelques difficultés à réaliser mon script.

En fait, je souhaite attribuer des droits en fonctions des utilisateurs.
Pour celà, j'ai crée une table users contenant les champs email (clé primaire), login, mdp et droit.
De là, j'ai fait la page suivante:

Code : Tout sélectionner

<?php session_start(); require_once 'connect/param.inc.php'; if( !empty($_POST['loginM']) && !empty($_POST['mdpM']) ) { $login = $_POST['loginM']; $mdp = $_POST['mdpM']; if( verif($login , $mdp) == $data['droit'] ) { session_regenerate_id(); $_SESSION['droit'] = $data['droit']; } } function verif( $login , $mdp ) { if( isset($dbconnect) ) { $dbase = 'publications'; mysql_select_db($dbase , $dbconnect); $sql_login = mysql_real_escape_string($login); $sql_mdp = mysql_real_escape_string($mdp); $sql = "SELECT * FROM users WHERE login = '$sql_login' AND mdp = '$sql_mdp'"; $result = mysql_query($sql , $link); if( mysql_num_rows($result) > 0 ) { $data = mysql_fetch_assoc($result); return $data['droit']; } else return false; } } ?><!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" xml:lang="fr" lang="fr"> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> <title>Publications</title> </head> <body> <div id="index"> <h1>Publications</h1> <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" id="connect"> <fieldset><legend>Membre</legend> <div> <label for="loginM">Login : </label> <input type="text" name="loginM" id="loginM" size="10" /> <label for="mdpM">Mot de passe : </label> <input type="password" name="mdpM" id="mdpM" size="10" maxlength="10" /> </div> </fieldset> <div class="submit"> <input type="submit" value="Connection" /> <input type="hidden" name="action" value="Connection" /> </div> </form> <?php if( isset($_SESSION['droit']) ) { ?> <h2>Brouillons en cours</h2> <h2>Articles à consulter</h2> <?php } if( isset($_SESSION['droit']) && $_SESSION['droit'] == 'admin' ) { ?> <h2>Articles à valider</h2> <?php } ?> <h2>Articles en ligne</h2> </div> </body></html>
Dans ce script, je souhaite, à la soumission du formulaire, vérifier si le login et le mot de passe indiqués par l'utilisateur concordent avec une entrée de la table. Si c'est le cas, je cherche à récupérer les droits affectés à cet utilisateur afin d'afficher la page en conséquence.
Le soucis, c'est que çà ne fonctionne pas. :( Quelqu'un pourrait-il m'indiquer quelles sont mes erreurs voire me donner quelques conseils annexes ?

Merci.

Posté : 11 août 2006, 10:21
par Ryle
Il y a un problème de visibilité de tes variables dans ta fonction verif().

En effet, une variable définie en dehors d'une fonction n'est accessible par celle-ci qu'à condition d'avoir été déclarée explicitement comme globale (ou qu'elle soit super-globale comme $_POST, $_GET, etc.)

Ainsi pour utiliser $dbconnect qui est je suppose définie dans param.inc.php, il te faut ajouter dans ta fonction la ligne de déclaration suivante :
function verif(...) {
  global $dbconnect;

  if( isset($dbconnect) )
  ...
}
Une bonne habitude également à prendre lorsque tu fais un mysql_query() c'est d'ajouter un "or die" ensuite, en cas d'erreur mysql. En effet, php ne sait pas si la requête sql est correcte ou non, il se contente de l'exécuter. Du coup il vaut mieux prendre l'habitude d'ajouter :
$result = mysql_query($sql , $link) or die (mysql_error());
Ainsi si la syntaxe sql n'est pas bonne tu le vois tout de suite :)

Enfin, tu fais appel en dehors de ta fonction à $data['droit'] :
if( verif($login , $mdp) == $data['droit'] ) 
        { 
                session_regenerate_id(); 
                $_SESSION['droit'] = $data['droit']; 
        } 
Est ce que cette variable est bien définie ici ? (est ce qu'elle existe dans ton param.inc.php ?)

Bon y a peut être d'autres petites bricoles à corriger, mais ceci devrait déjà te permettre d'avancer un peu :)

Edit : et puis tant qu'on y est, un p'tit conseil pour ta table d'utilisateur : il vaut mieux utiliser un nombre en auto-incrément pour ta clé primaire. En effet, cela t'assure d'avoir un identifiant unique et qui ne sera jamais modifié (alors qu'un email peut changer).
Par ailleurs quand tu auras besoin de lier cette table à d'autre, tu seras obligé d'utiliser l'émail pour faire le lien, et si celui-ci change, faut que tu ailles le changer partout. Avec un identifiant spécifique, tu n'aurais pas à te soucier de ça, le lien sera toujours correct ;)

Posté : 11 août 2006, 11:34
par Chakra Spirit
Tout d'abord, merci d'avoir répondu si vite.

Tes conseils m'apportent beaucoup... ;)
Enfin, tu fais appel en dehors de ta fonction à $data['droit'] :

PHP:
<?php if( verif($login , $mdp) == $data['droit'] )
{
session_regenerate_id();
$_SESSION['droit'] = $data['droit'];
}

Est ce que cette variable est bien définie ici ? (est ce qu'elle existe dans ton param.inc.php ?)
Le fichier param.inc.php ne contient que les identifiants de connexion à la base SQL et la connexion en elle-même.
A priori, je pensais que si le login et le mot de passe étaient trouvés, la fonction verif() me renverrait la variable $data['droit'] mais là, d'un coup, j'ai un doute car je suis en train de me dire que je dois récupérer une chaîne texte plutôt que la variable.
Je ne peux pas tester de suite n'ayant pas php au boulot mais je pense m'orienter sur ceci :

Code : Tout sélectionner

<?php session_start(); require_once 'connect/param.inc.php'; if( !empty($_POST['loginM']) && !empty($_POST['mdpM']) ) { $login = $_POST['loginM']; $mdp = $_POST['mdpM']; if( verif($login , $mdp) == 'admin' ) { session_regenerate_id(); $_SESSION['droit'] = 'admin'; } if( verif($login , $mdp) == 'membre' ) { session_regenerate_id(); $_SESSION['droit'] = 'membre'; } } function verif( $login , $mdp ) { global $dbconnect; if( isset($dbconnect) ) { $dbase = 'publications'; mysql_select_db($dbase , $dbconnect); $sql_login = mysql_real_escape_string($login); $sql_mdp = mysql_real_escape_string($mdp); $sql = "SELECT * FROM users WHERE login = '$sql_login' AND mdp = '$sql_mdp'"; $result = mysql_query($sql , $link) or die (mysql_error()); if( mysql_num_rows($result) > 0 ) { $data = mysql_fetch_assoc($result); return $data['droit']; } else return false; } } ?><!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" xml:lang="fr" lang="fr"> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> <title>Publications</title> </head> <body> <div id="index"> <h1>Publications</h1> <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" id="connect"> <fieldset><legend>Membre</legend> <div> <label for="loginM">Login : </label> <input type="text" name="loginM" id="loginM" size="10" /> <label for="mdpM">Mot de passe : </label> <input type="password" name="mdpM" id="mdpM" size="10" maxlength="10" /> </div> </fieldset> <div class="submit"> <input type="submit" value="Connection" /> <input type="hidden" name="action" value="Connection" /> </div> </form> <?php if( isset($_SESSION['droit']) ) { ?> <h2>Brouillons en cours</h2> <h2>Articles à consulter</h2> <?php } if( isset($_SESSION['droit']) && $_SESSION['droit'] == 'admin' ) { ?> <h2>Articles à valider</h2> <?php } ?> <h2>Articles en ligne</h2> </div> </body></html>
Cà semble juste ?

J'en profiterais pour changer ma clé primaire mais le code ci-dessus ne devrait pas changer pour autant.

Encore merci pour la qualité de ta réponse. :)

Posté : 13 août 2006, 21:56
par Chakra Spirit
Salut,

désolé d'avoir mis si longtemps pour réapparaître... :oops:

Mon problème est résolu. J'ai du modifier encore deux trois petites choses mais c'est réglé... Je laisse le code des fois que çà serve à quelqu'un ou qu'un membre souhaite me faire une remarque sur quelquechose qui le titille... :wink:
<?php
session_start();

require_once 'connect/param.inc.php';

if( !empty($_POST['loginM']) && !empty($_POST['mdpM']) )
{
	$login = $_POST['loginM'];
	$mdp = $_POST['mdpM'];

	if( verif($login , $mdp) == 'admin' )
	{
		session_regenerate_id();
		$droit = 'admin';
	}
	if( verif($login , $mdp) == 'membre' )
	{
		session_regenerate_id();
		$droit = 'membre';
	}
}

function verif($login , $mdp)
{
	global $dbconnect;

	if( isset($dbconnect) )
	{
		$dbase = 'publications';
		mysql_select_db($dbase , $dbconnect);
	
		$sql_login = mysql_real_escape_string($login);
		$sql_mdp = mysql_real_escape_string($mdp);
		$sql = "SELECT * FROM users WHERE login = '$sql_login' AND mdp = '$sql_mdp'";
		$result = mysql_query($sql , $dbconnect) or die ( mysql_error() ); 
	
		if( mysql_num_rows($result) > 0 )
		{
			while( $data = mysql_fetch_assoc($result) )
				return $data['droit'];
		}
		else
			return false;
	}
}

?><!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" xml:lang="fr" lang="fr">

<head>

	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
	<title>Publications</title>

</head>
<body>

	<div id="index">
		<h1>Publications</h1>
		<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" id="connect">
			<fieldset><legend>Membre</legend>
				<div>
					<label for="loginM">Login : </label>
					<input type="text" name="loginM" id="loginM" size="10" />
					<label for="mdpM">Mot de passe : </label>
					<input type="password" name="mdpM" id="mdpM" size="10" maxlength="10" />
				</div>
			</fieldset>
			<div class="submit">
				<input type="submit" value="Connection" />
				<input type="hidden" name="action" value="Connection" />
			</div>
		</form>
<?php
if( isset($droit) )
{
?>
		<h2>Brouillons en cours</h2>
		<h2>Articles à consulter</h2>
<?php
}
if( isset($droit) && $droit == 'admin' )
{
?>
		<h2>Articles à valider</h2>
<?php
}
?>
		<h2>Articles en ligne</h2>
	</div>

</body></html>
Encore merci Ryle.. :)

Posté : 16 août 2006, 09:56
par Chakra Spirit
Bonjour,

C'est encore moi avec mon script de connexion. :(

Je viens de m'apercevoir qu'il y a un petit soucis... genre quand je me déconnecte, je retourne avec les paramètres initiaux mais si j'appuie sur le bouton précédent du navigateur, je retourne de nouveau dans la partie membre sans même rentrer le login et le mot de passe, ce qui est un peu gênant quand même. :lol:

Comment puis-je éviter çà ?
Je précise que je teste en local.

Par ailleurs, est-ce que
$sql_login = mysql_real_escape_string($login);
suffit ou bien ceci serait préférable:
$sql_login = stripslashes( htmlentities( trim( $login) ) );
Cà se trouve, c'est équivalent mais je ne suis pas sûr de mon coup. :?

Je vous relaisse le code actuel:
<?php

require_once './connect/param.inc.php';

if( isset($_POST['connecter']) && !empty($_POST['connecter']) )
{
	if( isset($_POST['loginM']) && !empty($_POST['loginM']) &&
		isset($_POST['mdpM']) && !empty($_POST['mdpM']) )
	{
		$login = $_POST['loginM'];
		$mdp = $_POST['mdpM'];

		if( verif($login , $mdp) == 'admin' )
		{
			session_start();
			$_SESSION['droit'] = 'admin';
		}
		if( verif($login , $mdp) == 'membre' )
		{
			session_start();
			$_SESSION['droit'] = 'membre';
		}
	}
}
if( isset($_POST['deconnecter']) && !empty($_POST['deconnecter']) )
{
	session_start();
	session_unset();
	session_destroy();
}

function verif($login , $mdp)
{
	global $dbconnect;

	if( isset($dbconnect) )
	{
		$dbase = 'publications';
		mysql_select_db($dbase , $dbconnect);
	
		$sql_login = mysql_real_escape_string($login);
		$sql_mdp = mysql_real_escape_string($mdp);
		$sql = "SELECT * FROM utilisateurs WHERE login = '$sql_login' AND mdp = '$sql_mdp'";
		$result = mysql_query($sql , $dbconnect) or die ( mysql_error() ); 
	
		if( mysql_num_rows($result) > 0 )
		{
			while( $data = mysql_fetch_assoc($result) )
				return $data['droit'];
		}
		else
			return false;

		mysql_free_result($result);
		mysql_close();
	}
}

?><!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" xml:lang="fr" lang="fr">

<head>

	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
	<title>Publications</title>

</head>
<body>

	<div id="index">
<?php
if( isset($_SESSION['droit']) )
{
?>

		<!--Brouillon-->
		<div id="brouillon">
			<h3>Brouillons en cours</h3>
		</div>

		<!--Articles à consulter-->
		<div id="consult">
			<h3>Articles à consulter</h3>
		</div>
<?php
}
if( isset($_SESSION['droit']) && $_SESSION['droit'] == 'admin' )
{
?>

		<!--Articles à valider-->
		<div id="valid">
			<h3>Articles à valider</h3>
		</div>
<?php
}
?>

		<!--Articles en ligne-->
		<div id="ligne">
			<h3>Articles en ligne</h3>
		</div>

		<!--Formulaire de (dé)connexion-->
		<div id="connect">
<?php
if( !isset($_SESSION['droit']) && empty($_SESSION['droit']) )
{
?>
			<h3>Connexion</h3>
			<a href="./newmember.php">Nouveau membre</a>
			<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
				<div>
					<label for="loginM">Login : </label>
					<input type="text" name="loginM" id="loginM" size="10" />
					<label for="mdpM">Mot de passe : </label>
					<input type="password" name="mdpM" id="mdpM" size="10" maxlength="10" />
					<input type="submit" value="Se connecter" />
					<input type="hidden" name="connecter" value="Connecter" />
				</div>
			</form>
<?php
}
if( isset($_SESSION['droit']) && !empty($_SESSION['droit']) )
{
?>
			<h3>Déconnexion</h3>
			<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
				<div>
					<input type="submit" value="Se déconnecter" />
					<input type="hidden" name="deconnecter" value="déconnecter" />
				</div>
			</form>
<?php
}
?>
		</div>

	</div>

</body></html>
Merci à vous. :wink:

Posté : 16 août 2006, 11:11
par thehawk
j'ai vu que tu utiliser les sessions mais il ne fat pas oublier que lorsque que tu quite le navigateur etc tes session sont encores presnete don je te propose de faire un fichier de "deconnexion" de la forme :
<?
session_start(); 
//suppression de la variable de session
session_unregister("nom");

//par mesure de sécurité, on détruit toutes les variables ainsi que la session en cours
session_unset();
session_destroy();
header("Location:index.php"); // avec un header pour revenir a ata page initialre a modifier biensur
?> 
en esperant que cela t aide ...

Posté : 27 août 2006, 04:00
par Chakra Spirit
Salut,

De retour de vacances, en pleine forme et tout et tout, je me relance dans mon script mais... flute ! çà ne marche toujours pas. :(

Dans le doute, j'ai bien ajouté session_unregister('droit'); mais le problème reste entier : Un simple clic sur la flèche précédente suffit à se reconnecter. Et puis, dès lors que j'utilise session_unset();, celà ne suffit-il pas à supprimer la variable ? Là, j'avoue que je suis dans les choux. :oops:

Aussi, tu me proposes de faire un fichier séparé mais le truc, c'est que je ne souhaite pas créer de nouvelle page. J'aimerais bien que la connexion et déconnexion reste sur la même page que pour les utilisateurs non connectés, les seules différences étant mes variables de session. :?

Je vois de nombreux sites qui fonctionnent ainsi mais je ne trouve pas de tuto qui explique comment faire; tous passent par une page externe.

Quelqu'un peut-il me renseigner ? :-k

Posté : 27 août 2006, 04:30
par Invité
Ah ! Je viens de rajouter header('Location:index.php'); et je n'ai plus ce problème. C'est déjà çà donc merci pour ton aide... O:)

Je n'ai plus qu'à comprendre une petite notion à savoir si ceci :
<?php $sql_login = mysql_real_escape_string($login); ?>
équivaut à celà :
<?php $sql_login = stripslashes( htmlentities( trim($login) ) ); ?>
J'ai vu la première syntaxe dans le livre PHP5 avancé et si mes souvenirs sont justes, la seconde syntaxe provient du site phpsecure mais j'ai l'impression que la seconde est plus sûre... J'ai raison ou je suis encore dans les choux ? :)

Posté : 27 août 2006, 18:34
par thehawk
Le php5 a mon avis n'est pas encore disponible surtout les serveurs ... pour le moment en tout cas .

Sinon question de securite si tu tu dit que c'est la meme chose alors la securite est la meme ...