Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: MySQL-kirjautuminen

Sivun loppuun

Triton [15.02.2008 18:47:30]

#

Terve!

Tein tossa jokunen kuukaisi sitten sellaisen kirjautumissysteemin, joka haki tunnusparit tekstitiedostosta, ja nyt sitten päätin toteuttaa saman MySQL -tietokannalla.

<?php

//Muodostetaan yhteys ja valitaan tietokanta
$yhteys = mysql_connect("localhost","root","********");
mysql_select_db("customdata",$yhteys);

//Tuodaan tunnus ja salasana -tiedot turvallisesti sovellukseen ja hashataan salasana
$hashpass = md5($_POST['pass']);
$user = $_POST['user'];

//MySQL -kysely: Etsii oikeita pareja tietokannasta
$kysely = mysql_query("SELECT * FROM customdata WHERE Tunnus = ('$user') AND Salasana = ('$hashpass')");

//Toistaa ylempää kunnes pari löytyy (tai ei löydy)
while ($tietue = mysql_fetch_array($kysely, MYSQL_ASSOC)) {

      //Muunnetaan tietokannan taulujen nimet PHP -muuttujiksi
      $db_user = $tietue["Tunnus"];
      $db_pass = $tietue["Salasana"];

      //Suoritetaan tunnusparien vertailu
      if ($user == $db_user && $hashpass == $db_pass)
 	      echo "Tunnukset täsmäsivät!";
      else
              echo "Tunnukset eivät täsmänneet!";
}


//Suljetaan yhteys
mysql_close($yhteys);

?>

Koodi toimii muuten, mutta if -tarkistuksen else -ehto ei koskaan tulostu, vaikka tunnuspari olisi väärä. Jos tunnuspari on väärä niin ei tulostu ruutuun mitään...

Toivonmukaan myös arvostelette koodin, ja kerrotte miten sitä voisi parantaa esim. turvallisuuden suhteen...

Metabolix [15.02.2008 19:00:29]

#

Valitset taulusta vain ne käyttäjätiedot, jotka täsmäävät. Jos siis tiedot ovat väärät, yhtään taulukon riviä ei tule valittua, jolloin myöskään while-silmukkaa ei suoriteta kertaakaan.

<?php
if ($tietue = mysql_fetch_array($kysely, MYSQL_ASSOC)) {
  echo "Löytyi.\n";
  if ($tietue = mysql_fetch_array($kysely, MYSQL_ASSOC)) {
    echo "Löytyi toinenkin! Kannassa taitaa olla virhe.\n";
  }
} else {
  echo "Ei löytynyt.\n";
}
?>

Voisi olla järkevää ottaa SQL-kyselystä salasana pois, jolloin saisi kannasta oikean käyttäjän tiedot. Jos mitään ei löydy, tulostetaan "tuntematon käyttäjä", ja väärän salasanan tapaus voidaan käsitellä erikseen.

Sami [15.02.2008 19:03:56]

#

Tuota... Eikös tuo ensin hae tuolla kyselyllä kaikki ne rivit tietokannasta, joissa tunnus on annettu tunnus ja salasana on annetun salasanan md5-hash? Sitten siinä käydään läpi nämä löytyneet rivit, joita on oletettavasti joko 0 (tunnusta ei löydy) tai 1 (tunnus löytyy) kappaletta. Toisin sanoen koko ehtolausetta ei koskaan edes voida suorittaa väärällä tunnus-salasana-parilla.

matpit [15.02.2008 19:10:58]

#

If tarkistuksen else -ehto ei koskaan tulostu koska sinä haet elsesi vastaisella ehdolla mysql tietokannasta tietoa, joten elsen mukaista tulosta ei tule ikinä tuolla koodilla. Sama asia, kuin "Jos 1 on 1 niin .. Tai jos 1 on 0 niin .."

$kyselyn sisällähän on kaikki rivit, joissa käyttäjänimi ja salasana täsmäävät, eli niitä on joko 1 tai 0. Sinä haet riviä jossa tunnus ja salasana ovat oikein. Elikkä jos käyttäjänimi ja salasana ovat oikein, niin rivien määrä on 1, muussa tapauksessa 0.

Itse toteuttaisin tuon niin, että hakisin mysql -tietokannasta kaikki rivit jotka täsmäävät käyttäjänimeen, ja sitten vertaisin käyttäjän syöttämää salasanaa tietokannassa olevaan salasanaan. Molempi parempi.

Turvallisuuden kannalta sen verran, että kannattaa käyttäjän rekisteröityessä muuttaa erikoismerkit <, >, ! ja ? vaikkapa tällä käyttäjäystävällisempään muotoon, tai sitten jos käyttäjänimi sisältää jonkin noista niin ei anneta rekisteröityä.

Triton [16.02.2008 10:38:18]

#

No tein teidän vinkkien pohjalta tälläisen koodin, ja nyt se sitte toimiikin:

<?php

//Muodostetaan yhteys ja valitaan tietokanta
$yhteys = mysql_connect("localhost","root","******");
mysql_select_db("customdata",$yhteys);

//Tuodaan tunnus ja salasana -tiedot turvallisesti sovellukseen ja hashataan salasana
$pass = md5($_POST['pass']);
$user = $_POST['user'];

//MySQL -kysely: Etsii oikeita pareja tietokannasta
$kysely = mysql_query("SELECT * FROM customdata WHERE Tunnus = ('$user') AND Salasana = ('$pass')");

//Tarkistetaan tunnusparit
if (mysql_fetch_array($kysely,MYSQL_ASSOC) == true)
        echo "Tunnus täsmäsi!";
else
        echo "Tunnus ei täsmännyt!";


 //Suljetaan yhteys
mysql_close($yhteys);

?>

Wizard [16.02.2008 15:39:21]

#

Suosittelen vakavasti ottamaan käyttöön UTF-8 koodauksen ja sitten käyttäjätunnus sekä salasana seuraavasti:

<?php

if (ctype_alnum($username) && ctype_alnum($password)):
 $kysely = mysql_query("SELECT * FROM customdata WHERE Tunnus = ('$user') AND Salasana = ('$pass')");

    //Tarkistetaan tunnusparit
    if (mysql_fetch_array($kysely,MYSQL_ASSOC) == true):
        echo "Tunnus täsmäsi!";
    else:
        echo "Tunnus ei täsmännyt!";
    endif;

endif;

?>

Tuo mysql_close() metodi on turha, PHP sulkee yhteyden automaattisesti. Nähtävästi voit kuitenkin tarvita tuota yhteyttä myöhemmin sivullasi joten on ihan turha availla ja sulkea yhteyksiä jatkuvasti, ne tuottavat turhia viiveitä.


--W--

Triton [16.02.2008 16:46:29]

#

Mitä toi ctype_alnum -funktio oikein tekee?

Antti Laaksonen [16.02.2008 17:25:04]

#

Funktio tutkii, muodostuuko merkkijono pelkistä numeroista ja (englannin kielen?) aakkosista.

Wizard [17.02.2008 20:14:33]

#

Manuaalia lainatakseni: ctype_alnum testaa a-z, A-Z ja 0-9 merkit.

Hyvin yleinen kun tehdään käyttäjäkirjautumisia, yleensäkin ottaen ctype_ -metodit ovat hyödyllisiä sekä lisäksi sitten htmlspecialchars ja _encode metodit.

-W-

punppis [19.02.2008 11:53:33]

#

Itse olen ainakin toteuttanut mielestäni helpomman (en sitten tietoturvatasosta tiedä) näin:

<?php

$username = $_POST["username"];
$password = md5($_POST["password"]);

$query = mysql_query("SELECT password FROM users WHERE username = '$username'");
$oikea_passu = mysql_result($query, 0, 0);

if($oikea_passu == $password) {
echo "OK";
}
else {
echo "Fail!";
}

?>

Ei oo sisennyksiä kun kirjotin suoraan tähän.

Wizard [19.02.2008 12:46:49]

#

punppis kirjoitti:

Itse olen ainakin toteuttanut mielestäni helpomman (en sitten tietoturvatasosta tiedä) näin:

<?php

$username = $_POST["username"];
$password = md5($_POST["password"]);

$query = mysql_query("SELECT password FROM users WHERE username = '$username'");
$oikea_passu = mysql_result($query, 0, 0);

if($oikea_passu == $password) {
echo "OK";
}
else {
echo "Fail!";
}

?>

Ei oo sisennyksiä kun kirjotin suoraan tähän.

Vastaus tietoturvaan:

SQL INJECTION


Sivun alkuun

Vastaus

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

Tietoa sivustosta