Webstatt.org - Community seit 2006 - 2012 (2024?)

captcha problem!

user-139
16.07.2007 14:46

so, da meine seite die ich betreue ständig spam im gaestebuch hat , wollte ich nen captcha einbauen soweit sogut,.

das einbauen funzt auch , .. mir macht nur die überprüfung probleme,.

also ich hab meine guest.php
        <td><img src="captcha/captcha.php?action=show" width="140" height="40" alt="Bild-Captcha" /></td>
<td><input type="text" name="sicherheitscode" value="<?php echo htmlspecialchars($_POST['sicherheitscode']); ?>" class="feld"/>


die captcha.php sieht aso aus
    $CAPTCHA_LENGTH = 5;    // Länge der Captcha-Zeichenfolge, hier fünf Zeichen
$FONT_SIZE = 15; // Schriftgröße der Zeichen in Punkt
$IMG_WIDTH = 140; // Breite des Bild-Captchas in Pixel
$IMG_HEIGHT = 40; // Höhe des Bild-Captchas in Pixel

// Liste aller verwendeten Fonts
$FONTS[] = '/ttf/XFILES';


// Unser Zeichenalphabet
$ALPHABET = array('A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'Q', 'J', 'K', 'L', 'M', 'N',
'P', 'R', 'S', 'T', 'U', 'V', 'Y',
'W', '2', '3', '4', '5', '6', '7'zwinkern;

// Wir teilen dem Browser mit, dass er es hier mit einem JPEG-Bild zu tun hat.
header('Content-Type: image/jpeg', true);


// Wir erzeugen ein leeres JPEG-Bild von der Breite IMG_WIDTH und Höhe IMG_HEIGHT
$img = imagecreatetruecolor($IMG_WIDTH, $IMG_HEIGHT);

// Wir definieren eine Farbe mit Zufallszahlen
// Die Farbwerte sind durchgehend und absichtlich hoch (200 - 256) gewählt,
// um eine "leichte" Farbe zu erhalten
$col = imagecolorallocate($img, rand(200, 255), rand(200, 255), rand(200, 255));

// Wir füllen das komplette Bild mit der zuvor definierten Farbe
imagefill($img, 0, 0, $col);

$captcha = ''; // Enthält später den Captcha-Code als String
$x = 10; // x-Koordinate des ersten Zeichens, 10 px vom linken Rand


for($i = 0; $i < $CAPTCHA_LENGTH; $i++) {

$chr = $ALPHABET[rand(0, count($ALPHABET) - 1)]; // ein zufälliges Zeichen aus dem definierten Alphabet ermitteln
$captcha .= $chr; // Der Zeichenfolge $captcha das ermittelte Zeichen anfügen

$col = imagecolorallocate($img, rand(0, 199), rand(0, 199), rand(0, 199)); // einen zufälligen Farbwert definieren
$font = $FONTS[rand(0, count($FONTS) - 1)]; // einen zufälligen Font aus der Fontliste FONTS auswählen

$y = 20 + rand(0, 20); // die y-Koordinate mit einem Mindestabstand plus einem zufälligen Wert festlegen
$angle = rand(0, 15); // ein zufälliger Winkel zwischen 0 und 30 Grad

/*
* Diese Funktion zeichnet die Zeichenkette mit den
* gegeben Parametern (Schriftgröße, Winkel, Farbe, TTF-Font, usw.)
* in das Bild.
*/
imagettftext($img, $FONT_SIZE, $angle, $x, $y, $col, $font, $chr);

$dim = imagettfbbox($FONT_SIZE, $angle, $font, $chr); // ermittelt den Platzverbrauch des Zeichens
$x += $dim[4] + abs($dim[6]) + 10; // Versucht aus den zuvor ermittelten Werten einen geeigneten Zeichenabstand zu ermitteln
}

imagejpeg($img); // Ausgabe des Bildes an den Browser
imagedestroy($img); // Freigeben von Speicher


ich möchte jetzt den eingegebenen code mit dem $captcha vergleichen , weiss jedoch nicht wie ?!

OS: Windows XP CPU: AMD Athlon XP 3200+ RAM: 512MB DDR PC3200 (Dual Channel) Mainboard: MSI K7n2 Delta-L HDD: 80GB WD Graka:Radeon 9600 Pro =>Alekeijer Straussbuwe
user-152
16.07.2007 15:31

value="<?php echo htmlspecialchars($_POST['sicherheitscode']); ?>"

Dann kannste dein Captcha auch gleich vergessen, wenn der Code ganz sauber im Quelltext steht.

Stichwort - mit Session arbeiten.
Und damit wird das ganze überprüft.

Vorteil:
- niemand sieht was in der Session steht
- wer kein Session-Cookie annimmt ist vermutlich ein Spamer, Spider oder Bot
- einfache und saubere Lösung

Avatar user-194
16.07.2007 17:08

Original von user-152
value="<?php echo htmlspecialchars($_POST['sicherheitscode']); ?>"

Dann kannste dein Captcha auch gleich vergessen, wenn der Code ganz sauber im Quelltext steht.

Das ist doch nur der Teil, um nach einem erneuten Anzeigen der Seite (vermutlich wegen falscher Eingaben?) das Feld automatisch wieder mit dem alten Wert auszufüllen...

Stichwort - mit Session arbeiten.
Und damit wird das ganze überprüft.

Da stimm ich natürlich zu. lächeln

user-152
16.07.2007 17:20

Nö wenn jemand den Code falsch eintippt, wird sofort ein neuer Code generiert.
Und das gleich zu beginn vom Script.

Ich mache das bisher in etwa so:

Wenn die Seite geladen wird, wo das Captcha angezeigt werden soll, wird erst eine Funktion aufgerufen, die den Code erstellt.
Natürlich muss die Seiten mit session_start() gefüttert werden.
Dann wird z.B. $_SESSION['code'] mit dem Code hinterlegt.
Das Captcha selber wird mit diesem Code von der Session angezeigt.

Beim Absenden wird auf eine externe PHP-Datei verlinkt, die dann diesen Code von $_SESSION['code'] und $_POST['code'] vergleicht.
Stimmt dann dieser Code überein, und wurden alle Felder ausgefüllt, stimmt die E-Mail-Adresse etc..., erst dann wird der Eintrag oder was weis ich in die DB geschrieben.

Stimmt der Code nicht überein, wird mittels Session eine Fehlermeldung erzeugt, die dann der User zu sehen bekommt, und der User wird wieder zum Eingabefeld vom Formular geleitet inkl. der Anzeige der Fehlermeldung. Und das gleiche Spiel geht von vorne los ... wieder neuen Code erstellen usw. usw. usw.

Die ganze Umleitungen (mit Header:Location) haben den Sinn, um zu verhindern das man die F5-Taste bemusst lächeln

Und zu guter letzt wird noch geprüft, ob überhaupt ein Session-Cookie vorliegt.
Falls nicht, erfolgt kein Eintrag.

user-139
16.07.2007 20:10

aha kannste in etwa mal den session code präsentieren?
nur mal so wage,.

OS: Windows XP CPU: AMD Athlon XP 3200+ RAM: 512MB DDR PC3200 (Dual Channel) Mainboard: MSI K7n2 Delta-L HDD: 80GB WD Graka:Radeon 9600 Pro =>Alekeijer Straussbuwe
Avatar user-162
16.07.2007 23:10

Naja abhängig von der Komplexität deines Scriptes wird es halt irgendwie so aussehen:

$zahl = machIrgendeineZufallsZahl(); // Einen Code generieren
$_SESSION['geheim'] = $zahl; // Den Code als Session speichern
$captcha = macheinCaptchausderZahl($zahl); // Ein Captcha-Bild generieren
// Und nun halt das Übliche mit <form> etc.

Um das dann zu überprüfen machst du das:

$zahl = $_SESSION['geheim'];
$zahl2 = $_POST['geheim'];
if($zahl == $zahl2) {
// OK! Scheint kein Bot zu sein
// Eintrag wird in DB geschrieben
header("Location:XXX"zwinkern; // Weiterleiten zu einer Seite
} else {
// Scheint ein Bot zu sein
header("Location:YYY"zwinkern; // Zurück zum Formular -> Please try again
}

und denk immer daran session_start(); an den Anfang deines Scripts zu setzen, vor der ersten Ausgabe.

Perfection is not when there’s nothing to add, but when there’s nothing to take away swisscheek.com/magazine
user-152
17.07.2007 05:06

^^^ jo so ungefähr meinte ich das auch Fettes Grinsen

Als Passort-Funktion benutze ich allerdings eine andere Variante:


function GetPW( $anz = 5 , $md = 0 ) {
$st_1 = range ( 0 , 9 );
$st_2 = range ('a', 'z'zwinkern;
$st_3 = range ('A', 'Z'zwinkern;
$temp = array_merge( $st_1, $st_2, $st_3 );
srand ( (float)microtime() * 1000000);
shuffle ( $temp );
$out = '';
foreach ( $temp as $v ) {
if ($cc++ >= $anz) break;
$out .= $v;
}
if ($md == 1) return MD5($out); else return $out;
}


Dann muss ich nicht jeden Buchstaben extra in eine Array definieren.