Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

captcha Olivier pour formulaire [long]

17 réponses
Avatar
docanski
Je m'adresse plus particulièrement à Olivier sur ce coup puisque le
problème se situe au niveau de l'insertion de son captcha dans un
formulaire existant.
J'en restranscris ici l'essentiel pour une meilleure compréhension :

<copie register.php>
> <?php
>
> define('PUN_ROOT', './');
> require PUN_ROOT.'include/common.php';
>
>
> // If we are logged in, we shouldn't be here
> if (!$pun_user['is_guest'])
> {
> header('Location: index.php');
> exit;
> }
>
> // Load the register.php language file
> require PUN_ROOT.'lang/'.$pun_user['language'].'/register.php';
>
> // Load the register.php/profile.php language file
> require PUN_ROOT.'lang/'.$pun_user['language'].'/prof_reg.php';
>
> if ($pun_config['o_regs_allow'] == '0')
> message($lang_register['No new regs']);
>
>
> // User pressed the cancel button
> if (isset($_GET['cancel']))
> redirect('index.php', $lang_register['Reg cancel redirect']);
>
>
> else if ($pun_config['o_rules'] == '1' && !isset($_GET['agree']) && !isset($_POST['form_sent']))
> {
> $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_register['Register'];
> require PUN_ROOT.'header.php';
>
> ?>
> <div class="blockform">
> <h2><span><?php echo $lang_register['Forum rules'] ?></span></h2>
> <div class="box">
> <form method="get" action="register.php">
> <div class="inform">
> <fieldset>
> <legend><?php echo $lang_register['Rules legend'] ?></legend>
> <div class="infldset">
> <p><?php echo $pun_config['o_rules_message'] ?></p>
> </div>
> </fieldset>
> </div>
> <p><input type="submit" name="agree" value="<?php echo $lang_register['Agree'] ?>" /><input type="submit" name="cancel" value="<?php echo $lang_register['Cancel'] ?>" /></p>
> </form>
> </div>
> </div>
> <?php
>
> require PUN_ROOT.'footer.php';
> }
>
>
> else if (isset($_POST['form_sent']))
> {
> // Check that someone from this IP didn't register a user within the last hour (DoS prevention)
> $result = $db->query('SELECT 1 FROM '.$db->prefix.'users WHERE registration_ip=\''.get_remote_address().'\' AND registered>'.(time() - 3600)) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
>
> if ($db->num_rows($result))
> message($lang_register['User same IP']);
>
> $username = pun_trim($_POST['req_username']);
> $email1 = strtolower(trim($_POST['req_email1']));
>
> if ($pun_config['o_regs_verify'] == '1')
> {
> $email2 = strtolower(trim($_POST['req_email2']));
>
> $password1 = random_pass(8);
> $password2 = $password1;
> }
> else
> {
> $password1 = trim($_POST['req_password1']);
> $password2 = trim($_POST['req_password2']);
> }
>
> [...snip les différents autres contrôles... ]
>
>
> // Insert the new user into the database. We do this now to get the last inserted id for later use.
> $now = time();
>
> $intial_group_id = ($pun_config['o_regs_verify'] == '0') ? $pun_config['o_default_user_group'] : PUN_UNVERIFIED;
> $password_hash = pun_hash($password1);
>
> // Add the user
> $db->query('INSERT INTO '.$db->prefix.'users (username, group_id, password, email, email_setting, save_pass, timezone, language, style, registered, registration_ip, last_visit) VALUES(\''.$db->escape($username).'\', '.$intial_group_id.', \''.$password_hash.'\', \''.$email1.'\', '.$email_setting.', '.$save_pass.', '.$timezone.' , \''.$db->escape($language).'\', \''.$pun_config['o_default_style'].'\', '.$now.', \''.get_remote_address().'\', '.$now.')') or error('Unable to create user', __FILE__, __LINE__, $db->error());
> $new_uid = $db->insert_id();
>
>
> [...snip les différents contrôles... ]
>
> // Must the user verify the registration or do we log him/her in right now?
> if ($pun_config['o_regs_verify'] == '1')
> {
> // Load the "welcome" template
> $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/welcome.tpl'));
>
> // The first row contains the subject
> $first_crlf = strpos($mail_tpl, "\n");
> $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
> $mail_message = trim(substr($mail_tpl, $first_crlf));
>
> $mail_subject = str_replace('<board_title>', $pun_config['o_board_title'], $mail_subject);
> $mail_message = str_replace('<base_url>', $pun_config['o_base_url'].'/', $mail_message);
> $mail_message = str_replace('<username>', $username, $mail_message);
> $mail_message = str_replace('<password>', $password1, $mail_message);
> $mail_message = str_replace('<login_url>', $pun_config['o_base_url'].'/login.php', $mail_message);
> $mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message);
>
> pun_mail($email1, $mail_subject, $mail_message);
>
> message($lang_register['Reg e-mail'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.', true);
> }
>
> pun_setcookie($new_uid, $password_hash, ($save_pass != '0') ? $now + 31536000 : 0);
>
> redirect('index.php', $lang_register['Reg complete']);
> }
>
>
> $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_register['Register'];
> $required_fields = array('req_username' => $lang_common['Username'], 'req_password1' => $lang_common['Password'], 'req_password2' => $lang_prof_reg['Confirm pass'], 'req_email1' => $lang_common['E-mail'], 'req_email2' => $lang_common['E-mail'].' 2');
> $focus_element = array('register', 'req_username');
> require PUN_ROOT.'header.php';
> ?>
>
> <?php
> session_start();
>
> // Si le formulaire est validé, on vérifie la réponse
> // avec les valeurs de référence stockées en session
> if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
>
> list($word, $index, $position, $question) = $_SESSION['captcha'];
> $answer = substr($word, $index - 1, 1);
> $passed = ( (string)$_POST['captcha'] === (string)$answer );
>
> }
>
> // Sinon on génère un nouveau test en prenant un mot au
> // hasard ainsi qu'une position de lettre dans ce mot
> else {
>
> // Chargement de la liste des mots
> $words = file('words.txt');
>
> // Sélection d'un mot au hasard
> $word = trim($words[rand(0, count($words) - 1)]);
>
> // Génération de l'index de la lettre à saisir
> $index = rand(1, strlen($word));
>
> // Transformation de l'index en toutes lettres
> if ( $index == strlen($word) ) $position = 'dernière';
> elseif ( $index == strlen($word) - 1 ) $position = 'avant-dernière';
> else {
> require_once 'nel.php';
> $position = enlettres($index, NEL_NIEME);
> if ( $position == 'premier' ) $position = 'première';
> }
>
> // Construction de la question
> $question = 'Quelle est '.( substr($position, 0, 1) == 'a' ? 'l\'' : 'la ' ).preg_replace('/[\w]/e', '"&#".ord("$0").";"', $position).' lettre du mot &laquo; '.preg_replace('/[\w]/e', '"&#".ord("$0").";"', $word).' &raquo; ?';
>
> // Stockage de la valeur en session
> $_SESSION['captcha'] = array($word, $index, $position, $question);
>
> }
> // Extraction des infos depuis la session et le résultat du formulaire
> list($word, $index, $position, $question) = $_SESSION['captcha'];
> $captcha = ( isset($_POST['captcha']) ) ? $_POST['captcha'] : '';
> ?>
>
> <div class="blockform">
> <h2><span><?php echo $lang_register['Register'] ?></span></h2>
> <div class="box">
> <form id="register" method="post" action="register.php?action=register" onsubmit="this.register.disabled=true;if(process_form(this)){return true;}else{this.register.disabled=false;return false;}">
> <div class="inform">
> <div class="forminfo">
> <h3><?php echo $lang_common['Important information'] ?></h3>
> <p><?php echo $lang_register['Desc 1'] ?></p>
> <p><?php echo $lang_register['Desc 2'] ?></p>
> </div>
> <fieldset>
> <legend><?php echo $lang_register['Username legend'] ?></legend>
> <div class="infldset">
> <input type="hidden" name="form_sent" value="1" />
> <label><strong><?php echo $lang_common['Username'] ?></strong><br /><input type="text" name="req_username" size="25" maxlength="25" /><br /></label>
> </div>
> </fieldset>
> </div>
> <?php if ($pun_config['o_regs_verify'] == '0'): ?> <div class="inform">
> <fieldset>
> <legend><?php echo $lang_register['Pass legend 1'] ?></legend>
> <div class="infldset">
> <label class="conl"><strong><?php echo $lang_common['Password'] ?></strong><br /><input type="password" name="req_password1" size="16" maxlength="16" /><br /></label>
> <label class="conl"><strong><?php echo $lang_prof_reg['Confirm pass'] ?></strong><br /><input type="password" name="req_password2" size="16" maxlength="16" /><br /></label>
> <p class="clearb"><?php echo $lang_register['Pass info'] ?></p>
> </div>
> </fieldset>
> </div>
> <?php endif; ?> <div class="inform">
> <fieldset>
> <legend><?php echo ($pun_config['o_regs_verify'] == '1') ? $lang_prof_reg['E-mail legend 2'] : $lang_prof_reg['E-mail legend'] ?></legend>
> <div class="infldset">
> <?php if ($pun_config['o_regs_verify'] == '1'): ?> <p><?php echo $lang_register['E-mail info'] ?></p>
> <?php endif; ?> <label><strong><?php echo $lang_common['E-mail'] ?></strong><br />
> <input type="text" name="req_email1" size="50" maxlength="50" /><br /></label>
> <?php if ($pun_config['o_regs_verify'] == '1'): ?> <label><strong><?php echo $lang_register['Confirm e-mail'] ?></strong><br />
> <input type="text" name="req_email2" size="50" maxlength="50" /><br /></label>
> <?php endif; ?> </div>
> </fieldset>
> </div>
>
> <div class="inform">
> <fieldset>
> <legend><?php echo $lang_prof_reg['Localisation legend'] ?></legend>
> <div class="infldset">
> <label><?php echo $lang_prof_reg['Timezone'] ?>: <?php echo $lang_prof_reg['Timezone info'] ?>
> <br /><select id="time_zone" name="timezone">
> <option value="-12"<?php if ($pun_config['o_server_timezone'] == -12 ) echo ' selected="selected"' ?>>-12</option>
> [...snip les différentes options... ]
> <option value="14"<?php if ($pun_config['o_server_timezone'] == 14 ) echo ' selected="selected"' ?>>+14</option>
> </select>
> <br /></label>
> <?php
>
> $languages = array();
> $d = dir(PUN_ROOT.'lang');
> while (($entry = $d->read()) !== false)
> {
> if ($entry != '.' && $entry != '..' && is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php'))
> $languages[] = $entry;
> }
> $d->close();
>
> // Only display the language selection box if there's more than one language available
> if (count($languages) > 1)
> {
>
> ?>
> <label><?php echo $lang_prof_reg['Language'] ?>: <?php echo $lang_prof_reg['Language info'] ?>
> <br /><select name="language">
> <?php
>
> while (list(, $temp) = @each($languages))
> {
> if ($pun_config['o_default_lang'] == $temp)
> echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'" selected="selected">'.$temp.'</option>'."\n";
> else
> echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'">'.$temp.'</option>'."\n";
> }
>
> ?>
> </select>
> <br /></label>
> <?php
>
> }
> ?>
> </div>
> </fieldset>
> </div>
> <div class="inform">
> <fieldset>
> <legend><?php echo $lang_prof_reg['Privacy options legend'] ?></legend>
> <div class="infldset">
> <p><?php echo $lang_prof_reg['E-mail setting info'] ?></p>
> <div class="rbox">
> <label><input type="radio" name="email_setting" value="0" /><?php echo $lang_prof_reg['E-mail setting 1'] ?><br /></label>
> <label><input type="radio" name="email_setting" value="1" checked="checked" /><?php echo $lang_prof_reg['E-mail setting 2'] ?><br /></label>
> <label><input type="radio" name="email_setting" value="2" /><?php echo $lang_prof_reg['E-mail setting 3'] ?><br /></label>
> </div>
> <p><?php echo $lang_prof_reg['Save user/pass info'] ?></p>
> <div class="rbox">
> <label><input type="checkbox" name="save_pass" value="1" checked="checked" /><?php echo $lang_prof_reg['Save user/pass'] ?><br /></label>
> </div>
> </div>
> </fieldset>
> </div>
>
>
> <?php if ( isset($passed) ) : if ( TRUE === $passed ) : ?>
> <p><strong>Bravo</strong>, vous avez trouvé la bonne réponse ! <a href="<?php echo $_SERVER['PHP_SELF']; ?>">Recommencer</a>.</p>
> <?php else : ?>
> <p><strong>Désolé</strong>, ce n'est pas la bonne réponse !</p>
> <?php endif; endif; ?>
> <?php if ( !isset($passed) || !$passed ) : ?>
>
> <div class="inform">
> <fieldset>
> <legend>Test de captcha</legend>
> <p style="font-weight:bold">
> <?php echo $question; ?>
> <input type="text" name="captcha" size="1" maxlength="1" value="<?php echo $captcha; ?>" />
> <input type="submit" value="Valider" />
> </p>
> </fieldset>
> </div>
>
> <?php endif; ?>
>
> <p><input type="submit" name="register" value="<?php echo $lang_register['Register'] ?>" /></p>
> </form>
> </div>
> </div>
> <?php
>
> require PUN_ROOT.'footer.php';
</copie register.php>

Il existe donc 2 "submit" dans ce formulaire : l'un pour vérifier si la
réponse au captcha est bonne et l'autre pour l'enregistrement de
l'inscription.
Le problème est que le "submit" du captcha, même si la réponse est
fausse, enregistre l'inscription, et si on l'ignore (puisqu'il n'y a pas
de condition obligatoire ... passque je sais pas faire :-( ), le
"submit" d'enregistrement accepte celui-ci sans broncher.
Il faudrait donc que le contrôle soit effectif (c'est évidemment le but
de l'insertion de ce captcha) et que le "submit" d'enregistrement ne
puisse être validé tant que ce contrôle n'est pas fait.
Je précise que le fichier texte comportant les mots et le fichier
nel.php ont été installés dans le même dossier que le formulaire dont le
nom est "register.php".

Cordialement,
--
docanski

Portail et annuaire du nord-Bretagne : http://armorance.free.fr/
Guide des champignons d'Europe : http://mycorance.free.fr/
La vallée de la Rance maritime : http://valderance.free.fr/
Les côtes du nord de la Bretagne : http://docarmor.free.fr/

7 réponses

1 2
Avatar
Olivier Miakinen
Le 13/11/2008 20:17, docanski a écrit :
[...]



Je ne comprenais pas pourquoi je n'avais pas lu ce message avant, mais
je viens de comprendre :

-----------------------------------------------------------
Date: Thu, 13 Nov 2008 20:17:01 +0100
NNTP-Posting-Date: Thu, 13 Nov 2008 21:42:46 +0000 (UTC)
-----------------------------------------------------------

Ton ordinateur a prsè de 2 h 30 de retard.
Avatar
Olivier Miakinen
Le 13/11/2008 23:02, Olivier Miakinen a écrit :

Merci, j'ai trouvé le code généré : il est à
http://mycorance.free.fr/forum/register.php?agree=J%27accepte



Au fait, tu peux me désinscrire (om) car je n'y connais rien aux
champignons. Au passage, si tu ne lis pas fr.usenet.forums.annonces
(fufa), tu n'as peut-être pas vu qu'un forum fr.rec.champignons est
sur le point d'être créé...
Avatar
Laurent vilday
Olivier Miakinen :

-----------------------------------------------------------------
else if (isset($_POST['form_sent']))
{
// Check that someone from this IP didn't register [...]
-----------------------------------------------------------------

Le code en question sera par exemple :

-----------------------------------------------------------------
else if (isset($_POST['form_sent']))
{
if (!isset($_POST['captcha']) || $_POST['captcha'] != 4) {
// Si l'utilisateur n'a pas répondu à la question ou s'il
// ne sait pas calculer.
message('Erreur : 2 + 2 = 4');
}
// Check that someone from this IP didn't register [...]
-----------------------------------------------------------------



Attention, HS du problème captcha mais pour le moins important IMO :
Ne pas utiliser isset() en PHP lorsque l'on veut déterminer l'existence
d'une clé dans un tableau (cf doc)
<http://fr.php.net/isset>

isset() détermine si une variable est affectée. En l'occurrence ce qui
est souhaité c'est déterminer si la clé d'un tableau existe. Et pour ce
faire, la "bonne" méthode c'est array_key_exists()
<http://fr.php.net/array_key_exists>

$tbl = array( 'foo' => null );
var_dump(isset($tbl['foo'])); // false
var_dump(array_key_exists('foo', $tbl)); // true

--
laurent
Avatar
Olivier Miakinen
[ Publication dans deux groupes, suivi dans un seul ]

Le 14/11/2008 04:51, Laurent vilday a écrit :

Attention, HS du problème captcha mais pour le moins important IMO :
Ne pas utiliser isset() en PHP lorsque l'on veut déterminer l'existence
d'une clé dans un tableau (cf doc)
<http://fr.php.net/isset>

isset() détermine si une variable est affectée. En l'occurrence ce qui
est souhaité c'est déterminer si la clé d'un tableau existe. Et pour ce
faire, la "bonne" méthode c'est array_key_exists()
<http://fr.php.net/array_key_exists>

$tbl = array( 'foo' => null );
var_dump(isset($tbl['foo'])); // false
var_dump(array_key_exists('foo', $tbl)); // true



D'accord dans le cas où un tableau peut contenir des valeurs NULL, *et*
que l'on veut les considérer comme existantes. Pas d'accord si l'on veut
considérer les valeurs NULL comme des valeurs inexistantes (dans ce cas,
c'est bien isset qu'il faut utiliser et pas array_key_exists).

En ce qui concerne les tableaux $_POST, $_REQUEST, etc., on ne peut y
trouver que des valeurs de type chaîne de caractères, et donc les deux
méthodes sont équivalentes.

[ Je fais suivre vers fr.comp.lang.php ]
Avatar
docanski
Alors que les eleveurs et agriculteurs polluent toujours la Bretagne,
Olivier Miakinen ecrit ce qui suit en ce 13.11.2008 23:06 :

Ton ordinateur a prsè de 2 h 30 de retard.



Non, non ! Il est à l'heure mais c'est parce que je n'avais pas envoyé
le message directement après l'avoir écrit : je suis actuellement en RTC
et rédige d'abord puis envoye ensuite à la connexion suivante.
--
docanski

Portail et annuaire du nord-Bretagne : http://armorance.free.fr/
Guide des champignons d'Europe : http://mycorance.free.fr/
La vallée de la Rance maritime : http://valderance.free.fr/
Les côtes du nord de la Bretagne : http://docarmor.free.fr/
Avatar
docanski
Alors que les eleveurs et agriculteurs polluent toujours la Bretagne,
Olivier Miakinen ecrit ce qui suit en ce 13.11.2008 23:18 :

Au fait, tu peux me désinscrire (om)



OK, je le ferai ce soir.

Au passage, si tu ne lis pas fr.usenet.forums.annonces
(fufa), tu n'as peut-être pas vu qu'un forum fr.rec.champignons est
sur le point d'être créé...



Je ne lis pas, en effet, mais il existe(ait ?) un forum dédié depuis des
années et il est (était ?) désert de chez désert.
--
docanski

Portail et annuaire du nord-Bretagne : http://armorance.free.fr/
Guide des champignons d'Europe : http://mycorance.free.fr/
La vallée de la Rance maritime : http://valderance.free.fr/
Les côtes du nord de la Bretagne : http://docarmor.free.fr/
Avatar
docanski
Alors que les eleveurs et agriculteurs polluent toujours la Bretagne,
Olivier Miakinen ecrit ce qui suit en ce 13.11.2008 23:02 :

éventuellement un lien vers le code source complet.


http://mycorance.free.fr/forum/register.php



Ça, c'est aussi du code généré. ;-)



Bé non : c'est le script PHP comportant les contrôles et le formulaire,
que j'ai reproduit une partie dans mon message initial


Le code en question sera par exemple :
-----------------------------------------------------------------
else if (isset($_POST['form_sent']))
{
if (!isset($_POST['captcha']) || $_POST['captcha'] != 4) {


etc ...
-----------------------------------------------------------------
Bien entendu, il faut avoir inclus quelque part dans le formulaire, pas
très loin du <input type="text" name="req_username" ... />, un <input
type="text" name="captcha" ... />, accompagnant la question de combien
font 2 et 2.



Apparemment, nous ne sommes pas sur la même longueur d'onde pour ce
captcha puisque tu reviens avec *une* opération arithmétique. Soit, je
veux bien continuer par là (faudra que j'essaye d'installer ce qui
précède dans le fichier et le tester ensuite) mais celui que j'évoquais
à l'origine était basé sur une série de mots (groupés dans un fichier
words.txt), un script nel.php commenté en tête par un :
# Fichier : nel.php (Nombres En Lettres)
#
# Auteur : Olivier Miakinen
# Création : mercredi 2 avril 2003
# Dernière modification : samedi 1er mai 2004
# etc ...
et un fichier index.php contenant le formulaire simple destiné à servir
d'exemple. C'est à partir de ce dernier que j'ai tenté d'installer le
code dans mon propre formulaire.

Points à vérifier, car je n'ai pas pu voir le code correspondant :


...

J'attendrai d'y voir plus clair pour le choix de l'un ou de l'autre
avant de continuer, je crois que ce sera plus judicieux. A toi de voir
vers quel choix tu veux me diriger : je te suis comme ton ombre ;-) ,
sachant que le plus simple sera le mieux et que je ne vise que l'efficacité.

Cordialement,
--
docanski

Portail et annuaire du nord-Bretagne : http://armorance.free.fr/
Guide des champignons d'Europe : http://mycorance.free.fr/
La vallée de la Rance maritime : http://valderance.free.fr/
Les côtes du nord de la Bretagne : http://docarmor.free.fr/
1 2