Hei,
Tässä pieni pulma. Jos kirjautuminen epäonnistuu pyydetään käyttäjää syöttämään captcha (joka tulee kuvana), mutta miten saada captchan arvo "ylös", koska kun käyttäjä painaa uudelleen login, captcha palauttaa uuden arvon, jolloin käyttäjän arvo tulee aina yhdellä perässä. (Javascriptillä ehkä?)
Palautetaan captchan arvo taulukossa, jossa "word" -sanan tilalle tulee 8 merkkinen numerosarja esim. 7kJ0OhGu ja kuva.
Jos painettu login painiketta:
if (isset($_POST['login'])){ $captcha = strong_captcha(); $username = @$_POST['username']; $password = @$_POST['password']; $user_captcha = @$_POST['captcha']; $right_captcha = $captcha['word']; $login = new login($username, $password); $logReturn = $login->login($user_captcha, $right_captcha); }
Ja toiminnallisuus kirjautumiselle:
class login{ private $username; private $password; function __construct($username, $password) { $this->username = $username; $this->password = $password; } function login($user_captcha = '', $right_captcha = '', $status = 'active'){ $this->username = replace($this->username); $this->password = replace($this->password); $mysql_driver = new mysql_driver(); $mysql_driver->db_connect(); $mysql_driver->db_select(); $mysql_driver->db_query("Select id, password, username from users where username = '$this->username' and password = '$this->password' and status = '$status'"); $row = $mysql_driver->fetchArray(); $rowId = $row['id']; $password = $row['password']; $username = $row['username']; if($rowId != null && strval(intval($rowId)) == strval($rowId) && $rowId != 0 && !empty($rowId)){ if(strcmp($password, $this->password) == 0){ if(strcmp($username, $this->username) == 0){ if($user_captcha == $right_captcha){ //session_start(); //$_SESSION['id'] = <kesken vielä>; redirect("index.php?page=etusivu"); }else{ return false; } } else{ return false; } } else{ return false; } } else{ return false; } } }
Ja kyllä tämä on vielä muutenkin vähän vaiheessa, koska nyt kun captchan iffitys on sisällä, ei päästä koskaan loppuun asti, vaikka captchaa ei kysyttäisi... mutta alkuperäinen ongelma on tärkeämipi.
Ps. parannusehdotuksia voi muutenkin antaa, jos on aivan kuraa...
Sinun pitää tietenkin tallentaa oikea vastaus johonkin (esimerkiksi tietokantaan) silloin, kun tulostat kysymyksen käyttäjälle.
Ihan ensi töiksesi voisit kuitenkin muuttaa nuo if-else-hässäkät järkevämmiksi. Tässä on neljä parempaa tapaa:
Pitää nuo iffitykset muuttaa, mutta tietokanta ei tässä tapauksessa tunnu järkevältä, joten mieluiten joku muu vaihtoehto...
Miksi tietokanta ei tunnu järkevältä? Mikä sitten tuntuu järkevältä? Piilokenttä ja eväste eivät tule kysymykseen. Jos käytät istuntoa, voit tietenkin tallentaa tiedon sinne.
Tietokanta kävi itelläkin kyllä mielessä, mutta tuntuu vähän turhalta... eikö javascriptillä saisi tätä esimerkiksi tehtyä?
Et voi käyttää tähän mitään selainpuolella toimivaa tekniikkaa. Tarkistus pitää pystyä tekemään PHP:llä.
Selvä se. Pitää sitten tehdä tietokannan avulla. Ilmeisesti siinä pitää tosin ottaa huomioon käyttäjän ip-osoite, koska jos monta ihmistä syöttää numerosarjaa samaan aikaan, että ei mene sitten sekaisin.
Älä sotke IP-osoitetta tähän. Laita lomakkeelle piilokenttään jokin vastausta kuvaava tieto kuten rivin id tietokannassa tai vaikka vastauksesta turvallisesti laskettu tiiviste. Lisäksi kannattaa tallentaa tietokantaan aikaleima, jotta voit poistaa vanhentuneet rivit. Käytetyt rivit pitää tietenkin poistaa saman tien.
Yksi tapa on antaa captchalle seed, jonka perusteella varsinainen captcha-merkkijono generoidaan. Tämän seedin voi välittää myös lomakkeen mukana, jolloin ei tarvita tietokantaa eikä sessioita eikä mitään.
function build_captcha_string($seed) { $salt = 'abcdefg#!¤%&/$£@'; $captcha = substr(md5($seed . $salt), 0, 5); $captcha = strtoupper($captcha); return $captcha; } $seed = get_value('seed'); $captcha = build_captcha_string($seed);
Ongelmana tässä on kuitenkin se, että hyökkääjä voi arvata samaa captchaa uudestaan ja uudestaan.
---
Mielestäni captchan validointi ei kuulu login-toimintoon vaan yleiseen lomakkeen validointiin. Captchoja voi olla millä tahansa lomakkeella, joten ei ole järkevää joutua kirjoittamaan joka kerta uusi validointikoodi samalle asialle.
Palaisin alkuperäiseen kysymykseen sen verran, että miten niin captcha tulee aina "yhdellä perässä"? Yleensähän captcha toteutetaan siten, että:
1) sivu, jossa on <img>-tagi, johon captcha halutaan, tämän kuvan src attribuutti on viittaus PHP-sivuun, joka muodostaa dynaamisen kuvan
2) kun kuvaa haetaan palvelimelta, PHP koodilla arvotaan captcha, luodaan dynaaminen kuva ja samalla laitetaan sessioon tuo numero-,kirjain-lukusarja
3) käyttäjä syöttää arvon nähdessään kuvan
4) vertaillaan session arvoa ja käyttäjän syöttämää arvoa
Jos tuo on loogisesti/ohjelmallisesti vaikeaa, voi kokeilla vaikka Googlen tarjoamaan reCaptcha palvelua: http://www.google.com/recaptcha/captcha
Aihe on jo aika vanha, joten et voi enää vastata siihen.