Ongelmani on että olen tekemässä rekisteröitymistä ja kirjautumista. Kun joku pelaaja esim. "NimiPuU" niin tietokantaan se tallentuu samalla tavalla niinkuin pitää. Ongelma on kuitenkin kun pelaaja kirjautuu hän syöttää käyttäjänimen ja salasanan. Php:ni tarkistaa että löytyykö pelaajaa ja sen jälkeen katsoo onko salasana sama kuin syötetty. Käyttäjänimeksi kuitenkin voi syöttää "nimipuu" tai "nImIpUu" yms. Eli tietokannasta hakiessa se hylkää kaikki isot kirjaimet ja pienet eikä välitä vaikka haluaisin koodin toimimaan siten että kirjautuessa isoilla ja pienillä on väliä mutta rekisteröityessä ei ole väliä silloin kun se hakee onko saman nimisiä.
Esim.
Rekisteröidyn nimellä "AbCdef"
//Tällöin kukaan ei voi enään rekisteröityä samoilla kirjaimilla esim "abcdef" ei toimi.
Sitten kun kirjaudun haluan että käyttäjä joutuu syöttämään "AbCdef" samalla tavalla vaikka ei ole mahdollista että on "abcdef" nimenä.
Tässä viellä rekisteröitymiskoodi:
<?php $servername = "localhost"; $server_username = "kayttaja"; $server_password = 'salasana'; $dbName = "tietokanta"; $username = $_POST["usernamePost"]; $password = $_POST["passwordPost"]; $email = $_POST["emailPost"]; // muodostetaan yhteys tietokantaan try { $yhteys = new PDO("mysql:host=$servername;dbname=$dbName", "$server_username", "$server_password"); } catch (PDOException $e) { die("VIRHE: " . $e->getMessage()); } // virheenkäsittely: virheet aiheuttavat poikkeuksen $yhteys->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // merkistö: käytetään latin1-merkistöä; toinen yleinen vaihtoehto on utf8. $yhteys->exec("SET NAMES latin1"); if($username != "" && $password != "" && $email != "" && count($username) > 3 && count($password) > 5){ try { $kysely = $yhteys->prepare("INSERT INTO pokerusers (username, password, email, chipWallet) VALUES (?, ?, ?, 10000)"); $kysely->execute(array($username, $password, $email)); echo "ok"; //hakee pelaajan id:n. $kysely = $yhteys->prepare("SELECT id FROM pokerusers WHERE username = ?"); $kysely->execute(array($username)); $tulos = $kysely->fetch(PDO::FETCH_OBJ); $id; foreach($tulos as $id){} } catch (PDOException $e) { echo "There was error adding user to database"; } }else{ echo "We get your ip and we will contact police if you try to hack this site again."; } ?>
Ja kirjautuminen:
<?php $servername = "localhost"; $server_username = "käyttäjä"; $server_password = 'salasana'; $dbName = "tietokanta"; $username = $_POST["usernamePost"]; $password = $_POST["passwordPost"]; // muodostetaan yhteys tietokantaan try { $yhteys = new PDO("mysql:host=$servername;dbname=$dbName", "$server_username", "$server_password"); } catch (PDOException $e) { die("VIRHE: " . $e->getMessage()); } // virheenkäsittely: virheet aiheuttavat poikkeuksen $yhteys->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // merkistö: käytetään latin1-merkistöä; toinen yleinen vaihtoehto on utf8. $yhteys->exec("SET NAMES latin1"); $kysely = $yhteys->prepare("SELECT password FROM pokerusers WHERE username = ?"); $kysely->execute(array($username)); $tulos = $kysely->fetch(PDO::FETCH_OBJ); $realPassword; foreach($tulos as $realPassword){} if($realPassword == $password){ echo "ok"; }else{ echo "error"; } ?>
Määrittelet tietokantaan, että collation on "case sensitive" tai binary, niin haku toimii isot ja pienet kirjaimet erotellen.
Yleisesti ottaen en pidä hyvänä ideana että voi olla eri käyttäjiä joiden nimessä on vain kirjainten kokoero, mutta tätähän et kysynyt :)
Kiitos vastauksesta voi ollakin että ehdottamasi juttu on yksinkertaisempi.
No onhan se nyt käyttäjälle selkeästi yksinkertaisempi, kun ei tarvitse lotota, että mitkä kirjaimista olivat versaaleilla ja mitkä eivät. Ratkaisu on siis jopa tietoturvan kannalta parempi, kun ei huomioida kirjainkokoa kirjautumisen yhteydessä.
kannattanee lisätö myös tarkistus käyttäjän luontiin, että samaa käyttäjätunnusta ei voi lisätä useaan kertaan. try catchisi ei oikein tuota asiaa aja, vaikkakin se siihen kosahtaa jos unique constraint on päällä username kentässä (käyttäjälle pitäisi saada vähän yksinkertaisempi ilmoitus takaisin kuin että error sitä ja tätä). Vai oletko tarkoituksella sallimassa sen, että sama käyttäjätunnus voi olla useaan kertaan, ja salasana ainoastaan erottaa ne toisistaan? Siinä tapauksessa tarkistus pitää tehdä sille, että salasanat samoilla tunnuksilla ei voi olla samoja.
E1ss kirjoitti:
$realPassword; foreach($tulos as $realPassword){}
Toistat tätä ihmeellistä rakennetta monessa kohdassa. Tässä on nyt jokin väärinkäsitys. Ensimmäinen rivi ei tee yhtään mitään, eli sen voit poistaa. (Tai jos rivin tarkoitus on varmistaa, että muuttuja on tyhjä, muuttujaan pitäisi vaikka sijoittaa null.) Toinen rivi on ”ihan kätevä”, mutta oikeasti olisi selvempää hakea arvo sen nimellä. Oikea koodi näyttäisi siis vaikka tältä:
if (!$tulos) { throw new Exception("Tietoa ei löydy!"); } $realPassword = $tulos->password;
Aihe on jo aika vanha, joten et voi enää vastata siihen.