Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Captchan edellisen arvon talteen ottaminen

Sivun loppuun

Query [28.05.2012 21:13:20]

#

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.

return array('word' => $word, 'image' => $img);

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...

Metabolix [28.05.2012 21:20:18]

#

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:

if (ehto) {
	if (ehto2) {
		toiminto();
		return true;
	}
}
return false;
if (ehto && ehto2) {
	toiminto();
	return true;
}
return false;
if (!(ehto)) {
	return false;
}
if (!(ehto2)) {
	return false;
}
// ...
toiminto();
if (!(ehto) || !(ehto2)) {
	return false;
}
toiminto();

Query [28.05.2012 21:22:30]

#

Pitää nuo iffitykset muuttaa, mutta tietokanta ei tässä tapauksessa tunnu järkevältä, joten mieluiten joku muu vaihtoehto...

Metabolix [28.05.2012 21:29:16]

#

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.

Query [28.05.2012 21:40:21]

#

Tietokanta kävi itelläkin kyllä mielessä, mutta tuntuu vähän turhalta... eikö javascriptillä saisi tätä esimerkiksi tehtyä?

Metabolix [28.05.2012 22:04:11]

#

Et voi käyttää tähän mitään selainpuolella toimivaa tekniikkaa. Tarkistus pitää pystyä tekemään PHP:llä.

Query [28.05.2012 22:07:44]

#

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.

Metabolix [28.05.2012 22:17:17]

#

Ä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.

The Alchemist [29.05.2012 06:34:22]

#

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.

ZeroGravity [30.05.2012 08:31:59]

#

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


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta