[RESOLU] Probléme avec cookies sur site en production

Eléphant du PHP | 418 Messages

18 janv. 2013, 07:06

Salutation à tous

Après avoir commencer l’internationalisation de mon site, j'ai remarquer que les cookies de connexion ne fonctionnaient pas.

De ce fait j'ai créer une table contenant le SiD d'un utilisateur, afin de l'envoyer en paramètre de valeur pour le cookie.

Voici ce que j'ai fait (en local cela fonctionne excellemment bien, mais pas en production)

Pour la connexion
					$expire = time() + 365*24*3600;
					/* **** */
					$query_id=$cnx->prepare('SELECT user_sid
					FROM t_user_sid
					WHERE users_id = :users_id');
					$query_id->bindValue(':users_id',$users_id, PDO::PARAM_INT);
					$query_id->execute() or die ('Erreur SQL');
					// Si il n'y a pas de donnée
					if ($query_id->rowCount()==0){
						if (!isset($_COOKIE['user_SiD'])){
							setcookie('user_SiD', $SiD, $expire, '/');
						}
						$query_sid=$cnx->prepare('INSERT INTO t_user_sid
						(users_id, user_sid)
						VALUES (:users_id, :user_sid)');
						$query_sid->bindValue(':users_id',$users_id, PDO::PARAM_INT);
						$query_sid->bindValue(':user_sid',$SiD, PDO::PARAM_STR);
						$query_sid->execute() or die ('Erreur SQL!');
						$query_sid->CloseCursor();
					}
					// Si il y a des données
					if ($query_id->rowCount()!=0){
						$data_id = $query_id->fetch();
						$SiD = $data_id['user_sid'];
						if (!isset($_COOKIE['user_SiD'])){
							setcookie('user_SiD', $SiD, $expire, '/');
						}
					}
					$query_id->CloseCursor();
Pour la déconnexion
if (isset($_COOKIE['lang'])){
	setcookie ("lang", '', time() - 3600, '/');
}
if (isset($_COOKIE['user_SiD'])){
	setcookie ("user_SiD", '', time() - 3600, '/');
}
Le hic, comme dit la la parenthèse c'est que la création du cookie "user_SiD" ne fonctionne pas en production (celui des langues fonction très bien), et lors de la déconnexion, je ne détruit pas les cookies (y compris celui de la langue), alors qu'en test local, tout fonctionne, et que la version de php du site de prod, est supérieur à celle du développement.

Auriez vous une idée du pourquoi du comment?

Merci beaucoup pour votre aide

Cordialement

ViPHP
AB
ViPHP | 5818 Messages

18 janv. 2013, 17:52

Quand un cookie n'est pas créé c'est souvent parce qu'il envoie une valeur vide ou que le path n'est pas le bon. Vérifies ta valeur $SiD et n'indique pas de path

Eléphant du PHP | 418 Messages

18 janv. 2013, 22:24

J'ai supprimer le path, et vérifier la valeur de SiD:

On affiche bien une valeur à SiD, et même sans le path, ça ne change pas, en local ça fonctionne mais pas en Prod.

Merci de votre aide

Cordialement

Eléphant du PHP | 418 Messages

20 janv. 2013, 14:58

Personne ne peux m'expliquer ce phénomène?

Je me demander est ce qu'il y aurais un rapport avec la configuration du serveur, sachant que j'arrive à créer les cookies de langues, mais pas à les détruire, et qu'il est toujours impossible de créer le cookie de SiD.

Merci beaucoup

Cordialement

Eléphant du PHP | 120 Messages

20 janv. 2013, 17:49

Active les messages d'erreur avec error_reporting(-1) ou va les chercher dans le log en question. Je suppose que ton serveur local mets l'output dans un buffer et que sur ton serveur non ; possible que tu envoies un contenu au client avant d'envoyer un cookie (qui n'est rien d'autre qu'un en-tête).

Eléphant du PHP | 418 Messages

20 janv. 2013, 21:11

Salut

Voici mon code (la partie permettant de créer les cookies
				
[...] Traitements post envoie de donnée
if (isset($_POST['souvenir']))
				{
					$Uid = $users_id;
					$key = "xxxx";
					$SiD=sha1($Uid.$key);
					$expire = time() + 365*24*3600;
					setcookie('uSiD', $SiD, $expire);
					error_reporting(-1);
					/* **** */
					$query_id=$cnx->prepare('SELECT user_sid
					FROM t_user_sid
					WHERE users_id = :users_id');
					$query_id->bindValue(':users_id',$users_id, PDO::PARAM_INT);
					$query_id->execute() or die ('Erreur SQL');
					// Si il n'y a pas de donnée
					if ($query_id->rowCount()==0){
						$query_sid=$cnx->prepare('INSERT INTO t_user_sid
						(users_id, user_sid)
						VALUES (:users_id, :user_sid)');
						$query_sid->bindValue(':users_id',$users_id, PDO::PARAM_INT);
						$query_sid->bindValue(':user_sid',$SiD, PDO::PARAM_STR);
						$query_sid->execute() or die ('Erreur SQL!');
						$query_sid->CloseCursor();
					}
					$query_id->CloseCursor();
				}

[...] Traitements en cas d'erreur
Merci

Eléphant du PHP | 418 Messages

23 janv. 2013, 05:53

je viens de permettre l'affichage des erreurs sur le site distant, voici le résulta

Pour connexion:

Code : Tout sélectionner

Warning: Cannot modify header information - headers already sent by (output started at /homepages/23/d438409960/htdocs/index.php:47) in /homepages/23/d438409960/htdocs/includes/deconnexion.php on line 10 Warning: Cannot modify header information - headers already sent by (output started at /homepages/23/d438409960/htdocs/index.php:47) in /homepages/23/d438409960/htdocs/includes/deconnexion.php on line 11 Warning: Cannot modify header information - headers already sent by (output started at /homepages/23/d438409960/htdocs/index.php:47) in /homepages/23/d438409960/htdocs/includes/deconnexion.php on line 12
Pour deconnexion:

Code : Tout sélectionner

Warning: Cannot modify header information - headers already sent by (output started at /homepages/23/d438409960/htdocs/index.php:47) in /homepages/23/d438409960/htdocs/includes/connexion.php on line 68 Warning: Cannot modify header information - headers already sent by (output started at /homepages/23/d438409960/htdocs/index.php:47) in /homepages/23/d438409960/htdocs/includes/connexion.php on line 69
Ce qui me parait bizarre, c'est comment ce fait il qu'en local je n'est aucune erreur?

Pour vous aider, voici le script complet de connexion.php et deconnexion.php

pour connexion.php
<?php
if (USERS_ID!=0) erreur(ERR_IS_CO);
else{
	if (isset($_GET['action']) && $_GET['action'] == "try") //On est dans la page de formulaire
	{
?>
		<form method="post" action="./connexion" enctype="multipart/form-data">
		  <div class="control-group">
			<label class="control-label" for="prependedInput"></label>
			<div class="controls">
			  <div class="input-prepend">
				<span class="add-on"><i class="icon-white icon-user"></i></span>
				<input class="input-large" name="login" size="16" type="text">
			  </div>
			  <div class="input-prepend">
				<span class="add-on"><i class="icon-white icon-asterisk"></i></span>
				<input class="input-large" name="password" size="16" type="password">
				<div class="help-block login-remember">
				  <label class="checkbox">
				  <input name="souvenir" value="1" type="checkbox"><?php echo $lang_maintien_connexion; ?>
				  </label>
				  <input name="connexion" class="btn" value="<?php echo $lang_connecter; ?>" type="submit">
				</div>
			  </div>
			  <a href="oublie"><?php echo $lang_pass_oublie; ?></a>
			</div>
		  </div>
		</form>
<?php
	}
	if (isset($_POST['connexion']))
	{
		extract($_POST);
		if (empty($login) || empty($password)){ //Oublie d'un champ
			alerte_connex($lang_erreur_connexion_message1);
		}
		else { //On check le mot de passe
			$query=$cnx->prepare('SELECT users_id, rank_id, users_name, users_pass, users_verif
			FROM t_users
			WHERE users_name = :login');
			$query->bindValue(':login',$login, PDO::PARAM_STR);
			$query->execute() or die ('Erreur SQL');
			$data=$query->fetch();
			$users_id=$data['users_id'];
			$users_pass=$data['users_pass'];
		if ($users_pass == encrypt($password)) // Acces OK !
		{
			//on verrifie que le membre ne soit pas bannis
			if ($data['rank_id'] == 1) //Le membre est banni
			{
				erreur(ERREUR_BAN);
			}
			if ($data['rank_id'] == 2) //Le membre est banni
			{
				erreur(ERREUR_ANNONYME);
			}
			elseif ($data['users_verif'] == 0) //Le membre n'est pas actif
			{
				erreur(ERREUR_NOT_ACTIF);
			}
			else //Sinon c'est ok, on se connecte
			{
				// si on a déja une langue défini, on créer un cookie avec une séssion plus longue
				if (!empty($lang) && isset($_COOKIE['lang'])){
					$langue_actuelle = $_COOKIE['lang'];
					$expire_negatif = time() - 60;
					$expire = time() + 365*24*3600;
					setcookie('lang', '', $expire_negatif);
					setcookie('lang', $langue_actuelle, $expire);
				}
				$mess_sucess = $lang_succes_connexion_message1.$data['users_name'].$lang_succes_connexion_message2;
				sucess($mess_sucess);
				/* ** */
				$id = 0;
				$_SESSION['users_name'] = $data['users_name'];
				$_SESSION['rank_id'] = $data['rank_id'];
				$_SESSION['users_id'] = $users_id;
				if (isset($_POST['souvenir']))
				{
					$Uid = $users_id;
					$key = "xxx";
					$SiD=sha1($Uid.$key);
					$expire = time() + 365*24*3600;
					setcookie('uSiD', $SiD, $expire);
					error_reporting(-1);
					/* **** */
					$query_id=$cnx->prepare('SELECT user_sid
					FROM t_user_sid
					WHERE users_id = :users_id');
					$query_id->bindValue(':users_id',$users_id, PDO::PARAM_INT);
					$query_id->execute() or die ('Erreur SQL');
					// Si il n'y a pas de donnée
					if ($query_id->rowCount()==0){
						$query_sid=$cnx->prepare('INSERT INTO t_user_sid
						(users_id, user_sid)
						VALUES (:users_id, :user_sid)');
						$query_sid->bindValue(':users_id',$users_id, PDO::PARAM_INT);
						$query_sid->bindValue(':user_sid',$SiD, PDO::PARAM_STR);
						$query_sid->execute() or die ('Erreur SQL!');
						$query_sid->CloseCursor();
					}
					$query_id->CloseCursor();
				}
				echo '<script type="text/javascript">setTimeout(function() {window.location.href="./";},2000);</script>';
			}
		}
		else // Acces pas OK !
		{
			alerte_connex($lang_erreur_connexion_message2);
		}
		$query->CloseCursor();
		}
	}
}
?>
pour deconnexion.php
<?php
$query=$cnx->prepare('DELETE FROM t_online WHERE online_id=:id');
$query->bindValue(':id',USERS_ID,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();

$langue_actuelle = $_COOKIE['lang'];
$expire_negatif = time() - 60;
$expire_nule = '0';
setcookie('lang', '', $expire_negatif);
setcookie('lang', $langue_actuelle, $expire_nule);
setcookie ('uSiD', '', $expire_negatif);

session_destroy();

	sucess($lang_succes_deconnexion_message);
	echo '<script type="text/javascript">setTimeout(function() { window.location.href="./"; },2000);</script>';
?>
Vous auriez une idée de ce qu'il faut que je regarde dans les configurations de php.ini afin de réparer ceci?

Merci beaucoup pour votre aide.

Cordialement

ViPHP
AB
ViPHP | 5818 Messages

23 janv. 2013, 17:30

Il ne faut rien faire afficher avant l'envoi d'un header, dans le cas contraire cela affiche ce message d'erreur.

Eléphant du PHP | 418 Messages

23 janv. 2013, 17:54

Je défini juste le code, je comprend pas.

Mais bon normalement les cookies sont créer à partir d'une page de connexion et en fonction de paramètres tel que cocher la case "Se souvenir de moi" et c'est dans le script.

Comment tu ferais pour créer un cookie de connexion et les supprimer lors de la déconnexion?

Merci pour ton aide

Cordialement

ViPHP
AB
ViPHP | 5818 Messages

23 janv. 2013, 19:32

Comment tu ferais pour créer un cookie de connexion et les supprimer lors de la déconnexion?
ça c'est le comportement typique d'un cookie de session.

Sinon, tu devrais éviter absolument de faire des redirections javascript générées par du code php. Utilses plutôt la fonction php : header('Location:monfichier.php');

Ensuite il est très déconseillé d'utiliser la fonction extract sur des données utilisateur. Mieux vaut faire
        if (isset($_POST['connexion']))
        {
           $login = isset($_POST['login']) ? $_POST['login'] : null;
           $password = isset($_POST['password']) ? $_POST['password'] : null;

           if (empty($login) || empty($password))
                 { //Oublie d'un champ
                        alerte_connex($lang_erreur_connexion_message1);
                 }
                 else
                 {
                      //..
                  }
  
        }

Eléphant du PHP | 418 Messages

24 janv. 2013, 09:21

Salutation

Après ton message, j'ai bien réfléchit à ce que me proposé PHP, et j'ai trouver une solution.

Dans la page connexion, je défini si on à cliquer sur "Se souvenir de moi", et je fait mes opérations tel que créer le code SiD, l'insérer dans la Bdd si il n’existe pas etc... Et je défini une variable de session SiD, me permettant de la passer sur toutes les pages (ou du moins celles dont j'ai besoin de cette valeur.
Ensuite, j'ai créer une page que j'inclus avant même l'entête du site (soit la balise "<!DOCTYPE html>"), et dans cette page je vérifie si on à une variable de session définit et non vide.
Si tel est le cas, alors je créer mon cookie.

Voici ce que ça donne

connexion.php
				if (isset($_POST['souvenir']))
				{
					$Uid = $users_id;
					$key = "xxx";
					$SiD=sha1($Uid.$key);
					$query_id=$cnx->prepare('SELECT user_sid
						FROM t_user_sid
						WHERE users_id = :users_id');
					$query_id->bindValue(':users_id',$users_id, PDO::PARAM_INT);
					$query_id->execute() or die ('Erreur SQL');
						// Si il n'y a pas de donnée
					if ($query_id->rowCount()==0){
						$query_sid=$cnx->prepare('INSERT INTO t_user_sid
						(users_id, user_sid)
						VALUES (:users_id, :user_sid)');
						$query_sid->bindValue(':users_id',$users_id, PDO::PARAM_INT);
						$query_sid->bindValue(':user_sid',$SiD, PDO::PARAM_STR);
						$query_sid->execute() or die ('Erreur SQL!');
						$query_sid->CloseCursor();
					}
						// Si il y a des données, on update le SiD si il est différent de celui qu'on a créer à l'instant ( $SiD )
					// if ($query_id->rowCount()==0){
					
					// }
					$query_id->CloseCursor();
					$_SESSION['user_sid'] = $SiD;
				}
define_cookie.php
<?php
	$expire = time() + 365*24*3600;
	$expire_negatif = time() - 60;
	$expire_nule = '0';
	// on vérifie que la page est celle de connexion
	if (isset($_SESSION['user_sid']) && !empty($_SESSION['user_sid'])){
		setcookie('uSiD', $_SESSION['user_sid'], $expire);
		$_SESSION['user_sid'] = null;
	}
	// on vérifie que la page est celle de deconnexion
	if (isset($_GET["p"]) && $_GET["p"]=='deconnexion'){
		if (isset($_COOKIE['lang']) && !empty($_COOKIE['lang'])){
			$langue_actuelle = $_COOKIE['lang'];
			setcookie('lang', '', $expire_negatif);
			setcookie('lang', $langue_actuelle, $expire_nule);
		}
		if (isset($_COOKIE['uSiD']) && !empty($_COOKIE['uSiD'])){
			setcookie ('uSiD', '', $expire_negatif);
		}
	}
?>
Normalement je pense que c'est la bonne méthode à adopté dans mon cas, sachant que ça fonctionne à merveille.

Mais n'ayant pas un niveau php super élevé, je vous saurais gré, en cas d’erreur, de me le signifier afin que je corrige cela.

Merci beaucoup pour votre aide.

Cordialement

[Edit]
Sinon, tu devrais éviter absolument de faire des redirections javascript générées par du code php. Utilses plutôt la fonction php : header('Location:monfichier.php');
Je le fait ainsi, j'ai eu trop de problème avec les header(), dés fois ça à le même comportement que mon problème, c'est pourquoi je l'utilise ainsi, de toute manière au pire, avec JS, ils clique sur accueil pour revenir à l'accueil si ils veulent, (si ils n'ont pas js activé)

Sinon je veux bien savoir comment tu gère tes redirections afin d'éviter les erreur de header déjà défini etc...

Merci beaucoup

ViPHP
AB
ViPHP | 5818 Messages

24 janv. 2013, 18:18

La page "connexion" me paraît bien construite. Pas de remarques particulière si ce n'est que tu utilise "$users_id" et on ne sait pas d'où vient cette variable mais bon tu l'as peut-être définie avant (autrement que par un extract sinon c'est carton rouge).

Par contre la page define_cookie.php est moins clean :
Que veux-tu faire en faisant :
if (isset($_COOKIE['lang']) && !empty($_COOKIE['lang'])){
                        $langue_actuelle = $_COOKIE['lang'];
                        setcookie('lang', '', $expire_negatif);
                        setcookie('lang', $langue_actuelle, $expire_nule);
                }
Si tu veux changer simplement le paramètre "expire", renvoie le cookie avec la bonne valeur ce qui écrasera l'ancien, pas besoin de l'effacer avant.

!empty() est plus contraignant que isset(). Donc dans une condition avec un "et" il suffit de mettre la plus contraignante.
Donc tu peux remplacer
if(isset($var) && !empty($var))
par
if(!empty($var))

Concernant les pb de header dans 99% des cas c'est que as mal organisé ton code (en faisant afficher quelque chose avant l'envoi d'un header). Il vaut mieux avoir une bonne organisation du code plutôt que d'essayer de rattraper l'affaire avec un echo javascript qui est une horreur de plus.

Pour une redirection php c'est un header location suivi d'un exit (pour être certain que le code suivant ne sera pas exécuté). Si tu veux aller vers index.php c'est donc
header('Location: index.php');
exit;

Eléphant du PHP | 418 Messages

24 janv. 2013, 23:13

Merci beaucoup

Ça me seras utilise, vraiment sympa.

Sujet résolut, et encore merci.

Cordialement