Du local au Web

Répondre
AndroWiiid
le 21/04/2010 à 20:38
AndroWiiid
Bonsoir,

Je me tourne vers vous parce que j'ai beau cherché une réponse à mon problème parmi mes bouquins ou les tutoriels, je ne trouve rien qui puisse m'aider.
Voici la situation :

J'ai développé mon site Web en local (Sans blague :p !) et je suis arrivé à un résultat que je juge plus que satisfaisant.
Une fois sure que tout était parfait, j'ai placé mon site web sur mon serveur (OVH).
Là, catastrophe. Une multitude de petites erreurs se glissent dans mon code. Certains notables, d'autres beaucoup moins.
Pour la plupart, j'ai réussis à résoudre le problème mais deux points persistent et sont plus qu'embêtant :

- mysql_real_escape_string : La fonction php mysql_real_escape_string() ne semble pas marché sur le Web. Est-ce normal
Voici un exemple de l'utilisation de cette fonction :
<?php
$_POST['pseudo'] = mysql_real_escape_string(htmlentities($_POST['pseudo']));
?>

Il me semble me manquer un paramètre mais je ne vois pas lequel.

- Session : Là repose mon plus gros problème. J'ai développé un système d'espace membre pour les visiteurs qui désirent s'inscrire mais voilà, une fois que quelqu'un se connecte sur mon site. Il se connecte bien mais s'il clique sur un lien interne au site, il est automatiquement connecté en tant que AndroWiid (moi). J'ai d'abord pensé un souci dans les variables $_SESSION mais je les ai affiché. Quand il se conecte, il y a bien ses identifiants dans les variables Sessions. J'ai beau cherché, je ne vois pas ce qui pourrait provoquer cela =/.

<?php
// Traitement du formulaire de connexion
if(isset($_POST['connexion']) && $_POST['connexion'] == 'Connexion')
{
$erreur_txt = '';
$erreur = 0;

//Mesure de sécurité.
$_POST['pseudo'] = mysql_real_escape_string(htmlentities($_POST['pseudo']));
$_POST['passwd'] = mysql_real_escape_string(htmlentities($_POST['passwd']));

// On vérifie si le pseudo est bien spécifié
if (!isset($_POST['pseudo']) || empty($_POST['pseudo']))
{
$erreur_txt .= 'Vous devez remplir le champ du pseudo !<br />';
$erreur++;
}

// On vérifie si le password est bien spécifié
if (!isset($_POST['passwd']) || empty($_POST['passwd']))
{
$erreur_txt .= 'Vous devez remplir le champ du password !<br />';
$erreur++;
}

if ($erreur == 0)
{
$_POST['pseudo'] = addslashes($_POST['pseudo']);
$_POST['passwd'] = md5($_POST['passwd']);

connexionbdd();
$sql = 'SELECT COUNT(*), rang, avatar, id
FROM membres
WHERE pseudo = "'.$_POST['pseudo'].'"
AND passwd = "'.$_POST['passwd'].'"';
$req = mysql_query($sql)
or die('Erreur SQL : <br />'.$sql.'<br />'.mysql_error());
$data = mysql_fetch_array($req);
mysql_close();

// On trouve le couple pseudo/passwd dans la bdd
if($data[0] == 1)
{
$_SESSION['admin'] = false;
$_SESSION['acces_autorise'] = true;
$_SESSION['pseudo'] = stripslashes($_POST['pseudo']);
$_SESSION['id'] = $data['id'];
$_SESSION['avatar'] = $data['avatar'];
if($data['rang'] >= 1)
{
$_SESSION['admin'] = true;
}

//header('Location: index.php');
//exit();
}
// On ne trouve pas le couple pseudo/passwd
elseif ($data[0] == 0)
{
header('Location: ?pages=erreur&err=20');
exit();
}
// Erreur avec la base de donnée
else
{
header('Location: ?pages=erreur&err=10');
exit();
}
}
}
?>


- Serveur : C'est la seule chose à laquelle j'ai pensé. Est-ce possible que cela soit la configuration chez OVH qui fasse déconner mon site comme ça ?

Merci d'avance pour vos réponses !
dark_nemo
le 22/04/2010 à 00:52
dark_nemo
Bon déjà un truc

mysql_real_escape_string doit être utilisé UNIQUEMENT lorsque la connexion à la base de données est établie.

Ensuite tu devrais afficher tes données pour les débugger

print_r($data); pour voir si les données sont bien conforme au jeu pseudo/password (fais le test avec plusieurs utilisateurs) et compare

print_r($_SESSION);
et navigue sur ton site pour voir la page qui change la session.
LupusMic
le 22/04/2010 à 10:35
LupusMic
Je plus-une dark_nemo sur mysql_real_escape_string et print_r (même si je préfère var_dump).

Ensuite quelques points :

<?php
//Mesure de sécurité.
$_POST['pseudo'] = mysql_real_escape_string(htmlentities($_POST['pseudo']));


Ceci est tout sauf une mesure de sécurité. Tout d'abord, tu modifie le tableau $_POST. C'est problématique car tu modifie la sémantique d'une donnée que tout le monde comprend comme étant l'ensemble des paramètres HTTP POST. En modifiant le tableau, tu prends le risque « d'oublier » que tu as modifier ce tableau. De plus, une mesure de sécurité doit être prise au bon moment. Pour mysql_real_escape_string, ceci correspond à l'insertion en base. Pour htmlentities, au moment de la création du corps de la réponse HTTP. De plus, htmlentities doit être utilisé différemment selon que ta donnée prendra place dans un text node ou un attribute node.

<?php

$_POST['pseudo'] = addslashes($_POST['pseudo']);

Ah ben tu as oublié que tu as déjà « protégé » les données soumises. Mais pourquoi tant de haine et utiliser addslashes ?

<?php
header('Location: ?pages=erreur&err=20');


1. La redirection doit être utilisée avec parcimonie (c'est l'enfer à déboguer, et ça contraint à une requête supplémentaire alors qu'on sait déjà quoi faire).
2. Je ne crois pas que ton URL est correctement formée
3. Les codes d'erreur en dur, c'est mal ©

Pour en revenir à ton problème, on s'en fout que tu rencontres des erreurs : on veut les voir ! Donc dis-nous quelles sont les erreurs qui surviennent lors de la mise en production.

Et par la même : versions PHP, modules installés, plate-forme de dev et celle de déploiement, etc
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
dark_nemo
le 22/04/2010 à 11:33
dark_nemo
Un truc général et qui évite pas mal de problèmes est de configurer son serveur local à l'identique du serveur utiliser en production.
Même version de php, même modules, même fichier de configuration etc

Pour les redirections je suis d'accord c'est lourd comme méthode. Le plus simple selon moi est d'indiquer à l'utilisateur son erreur (mettre les champs en rouge pas exemple et mettre une petite phrase explicative) c'est clair et facile à maintenir.

Puis un truc qui me saute aux yeux et que je trouve peu optimiser voir dangereux c'est d'afficher la requête en cas d'erreur. C'est vraiment à éviter
AndroWiiid
le 24/04/2010 à 14:48
AndroWiiid
Bonjour,

Merci pour toutes vos réponses vachement constructive. Alors comme il y a pas mal de truc à assimilé d'un coup, juste un petit topo histoire de voir si j'ai bien tout compris =) :

@dark_nemo

- mysql_real_escape_string : Ouaip, je m'en suis rendu compte par après. Maintenant, j'ai appelé ma fonction de connexion en début de code dans ma page index.php et mysql_close en fin de code de la même page. Histoire de ne plus devoir l'appeler et la fermer tout le temps.

- print_r($data) : Ouaip, on m'avait conseillé de marquer une fonction similaire me semble (var_dump()) et il affichait bien mes identifiants une fois que je naviguais sur mes pages en me connectant avec un autre compte. Le problème reposait sur un changement des variables à chaque changement de page. J'ai réglé le problème, je vais en parler plus bas.

@LupusMic

- Modification variable $_POST : Oui, on m'a fais la remarque et je me rend compte de ma bétise. Histoire de voir si c'est correcte, maintenant j'utilise la variable extract($_POST) avant tout chose puis je traite directement avec les variables $pseudo, ... qu'il me sort.

- addslashes : Effectivement, ce n'est pas la meilleure idée que j'ai eu x). J'enlève cela de suite.

- Redirection des erreurs : En faite, j'ai deux types d'erreur. La première est la sauvegarde dans une variable ($erreur_txt par exemple) des erreurs dans un formulaire que j'affiche directement sur la même page au dessus du formulaire. Au départ, je voulais faire uniquement comme ça. Après, je me suis rendu compte que certaines erreurs étaient un peu à part (comme erreur avec la base de donnée) et qu'elle revenait souvent dans mes requêtes. Donc, j'ai codé un script d'erreur qui affiche (selon la variable $_GET dans l'url, l'erreur a affiché). Ce n'est pas une bonne façon de faire ?

@dark_nemo

- Affichage des requêtes : C'était juste pendant que je programmais. Je les enlève une fois en ligne =).

Sinon, pour mon problème initial, il m'a fallu changé le nom de mes variables de session. Il semblait y avoir ambiguité avec d'autres variables de même nom (mais pas de même type). Depuis lors, ça marche sans problème.

Merci pour vos réponses vachement constructive !
moogli
le 26/04/2010 à 17:41
moogli
salut,

pour ce qui est de ton problème de nom de variable :
c'est tous a fait possible si le register global est à on.

dans ce cas si tu a $_POST['truc'], $_GET['truc'], $_SESSION['truc'] et $truc (marche avec $_COOKIE etc) tous cela represente la même variable, donc quand tu modifie $truc tu modifie le reste.
Où c'est genant ? lorsque tu utilise $login et $_SESSION['login'] par exemple. c'est un moyen de te retrouver avec des données d'un autre utilisateur (le pire étant $_SESSION['id'] je pense :) ).

pour eviter cela => ini_set('register_globals',0);
http://us2.php.net/manual/fr/ini.core.php#ini.register-globals
ceci n'est plus valable à partir de la version 5 quelques où le register globals est off par défaut.

@+
Il en faut peu pour être heureux !!!!!
LupusMic
le 26/04/2010 à 19:43
LupusMic
Modifier $_POST n'est pas stupide, ça manque juste d'élégance. Certaines personnes justifie la modification de $_POST pour des raisons de performances.

La gestion des erreurs n'est pas évidente, car il faut distinguer différents types d'erreurs. Les erreurs liées au fonctionnement du site et les erreurs liées à la logique de ton application.
Et tu t'en es bien rendu compte. Les erreurs générées par l'usage de la base de données ne doivent pas être traitées de la même manière que les erreurs de logique (mauvais prénom, etc).

Pour le problème de collision de noms de variables, c'est la raison pour laquelle j'ai précisé un préfixe dans la fonction extract.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Répondre

Ecrire un message

Votre message vient d'être créé avec succès.
LoadingChargement en cours