Opmerkingen op PDO script

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Snelle Jaap

Snelle Jaap

13/03/2014 11:48:15
Quote Anchor link
Hey,

Ik heb een beetje wat geprobeerd met een tutorial over PDO (dit keer inloggen).
Het begint een beetje duidelijk te worden, alleen snap ik sommige dingen nog niet helemaal.

Een paar vragen die ik niet zo snel op internet heb kunnen vinden:
Waar staat het FILTER_SANITIZE_STRING voor? Is dat een soort mysqli_real_escape ofzo?

Hoe werkt het try/exception principe precies? Is daar een duidelijke tekst voor te vinden ergens? Of kunnen jullie dat uitleggen?

En zijn er verder nog opmerkingen op de veiligheid van het script of verbeteringen?

Gr


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
    //begin session
    session_start();

    if(isset($_SESSION['user_id']))
    {

        $message = 'Gebruiker is al ingelogd';
    }

    
    //check that both username and password have been submitted
    if(!isset($_POST['phpro_username'], $_POST['phpro_password']))
    {

        $message = 'Voer een geldig gebruikersnaam en wachtwoord in.';
    }

    
    //check if the username is the correct length
    elseif (strlen( $_POST['phpro_username']) > 20 || strlen($_POST['phpro_username']) < 4)
    {

        $message = 'Gebruikersnaam mag minimaal 4 tekens lang zijn en maximaal 20 tekens.';
    }

    
    //check if the password is the correct length
    elseif(strlen($_POST['phpro_password']) > 20 || strlen($_POST['phpro_password']) < 4)
    {

        $message = 'Wachtwoord mag minimaal 4 tekens lang zijn en maximaal 20 tekens.';
    }

    
    //check the username has only alpha numeric characters
    elseif (ctype_alnum($_POST['phpro_username']) != true)
    {

        $message = 'Gebruikersnaam kan alleen getallen en letters bevatten.';
    }

    
    //check the password has only alpha numeric characters
    elseif (ctype_alnum($_POST['phpro_password']) != true)
    {

        $message = 'Wachtwoord kan alleen getallen en letters bevatten.';
    }

    else
    {
        // if we are here the data is valid and we can insert into database
        $phpro_username = filter_var($_POST['phpro_username'], FILTER_SANITIZE_STRING);
        $phpro_password = filter_var($_POST['phpro_password'], FILTER_SANITIZE_STRING);
        
        //password encryption
        $phpro_password = sha1($phpro_password);
        
        include_once ('connection.php');
        
        try{
            $dbh = new PDO("mysql:host=$mysql_hostname;dbname=$mysql_dbname", $mysql_username, $mysql_password);
            //send message when connected
            
            //set the error mode to exceptions

            $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            
            //prepare the select statement
            $stmt = $dbh->prepare("SELECT phpro_user_id, phpro_username, phpro_password
                    FROM phpro_users
                    WHERE phpro_username = :phpro_username
                    AND phpro_password = :phpro_password"
);
            
            //bind the parameters
            $stmt->bindParam(':phpro_username', $phpro_username, PDO::PARAM_STR);
            $stmt->bindParam(':phpro_password', $phpro_password, PDO::PARAM_STR, 40);
            
            //execute the prepared statement
            $stmt->execute();
            
            //check for a result
            $user_id = $stmt->fetchColumn();
            
            //if there is no result then show failure message
            if($user_id == false)
            {

                $message = 'Inloggen mislukt';
            }

            //else everything is fine
            else
            {
                $_SESSION['user_id'] = $user_id;
                
                $message = 'Je bent ingelogd!';
            }
            
        }
catch (Exception $ex) {
            //if we are here something went wrong with the database connection
            $message = 'Helaas is er wat mis gegaan tijdens het inloggen.';
        }
    }

   ?>


Toevoeging op 13/03/2014 11:52:47:

En Mathieu, als deze is 'goedgekeurd' heb je hier misschien wat aan?
 
PHP hulp

PHP hulp

22/12/2024 08:47:15
 
Michael -

Michael -

13/03/2014 12:07:12
Quote Anchor link
PHP FILTER_SANITIZE_STRING Filter
Quote:
The FILTER_SANITIZE_STRING filter strips or encodes unwanted characters.

This filter removes data that is potentially harmful for your application. It is used to strip tags and remove or encode unwanted characters.


Een soort van combi van strip_tags en htmlspecialchars.

Volgens mij krijg je de melding op regel 13 nu standaard als je de pagina opent?
Je controleert namelijk niet of er ge-post is (if($_SERVER['REQUEST_METHOD'] == 'POST'))
Verder ziet het er wel netjes uit.


Toevoeging op 13/03/2014 12:09:10:

en de try catch, moet je simpel zien als .. Proberen en opvangen... in Try wordt de code uitgevoerd, maar als dit fout gaat krijg je een 'exception'. Met catch kun je die exception opvangen en een eigen foutmelding weergeven.
 
Snelle Jaap

Snelle Jaap

13/03/2014 12:12:47
Quote Anchor link
Het wordt dus gebruikt als een soort beveiliging? Op die site niet echt duidelijk, hij telt daar de lengte van de string, maar dat doe je toch met strlen?

>>Volgens mij krijg je de melding op regel 13 nu standaard als je de pagina opent?
Je controleert namelijk niet of er ge-post is (if($_SERVER['REQUEST_METHOD'] == 'POST'))

Klopt inderdaad, hij checkt niet of er gepost is, dat kan ik nog wel toevoegen.

>>en de try catch, moet je simpel zien als .. Proberen en opvangen... in Try wordt de code uitgevoerd, maar als dit fout gaat krijg je een 'exception'. Met catch kun je die exception opvangen en een eigen foutmelding weergeven.

Wat is dan het voordeel om try catch te gebruiken? Het klinkt een klein beetje als if else, if code is goed = voer uit else = foutmelding.
Gewijzigd op 13/03/2014 12:16:44 door Snelle Jaap
 
Michael -

Michael -

13/03/2014 12:24:49
Quote Anchor link
>>> Het wordt dus gebruikt als een soort beveiliging? Op die site niet echt duidelijk, hij telt daar de lengte van de string, maar dat doe je toch met strlen?
Ja soort beveiliging. Je voorkomt hiermee dat bepaalde data wordt opgeslagen.

Hij telt niet de lengte van de string. Daar is inderdaad strlen() voor.
Wat je misschien bedoelt zijn de FLAGS
Quote:
Possible options and flags:

FILTER_FLAG_NO_ENCODE_QUOTES - This flag does not encode quotes
FILTER_FLAG_STRIP_LOW - Strip characters with ASCII value below 32
FILTER_FLAG_STRIP_HIGH - Strip characters with ASCII value above 127
FILTER_FLAG_ENCODE_LOW - Encode characters with ASCII value below 32
FILTER_FLAG_ENCODE_HIGH - Encode characters with ASCII value above 127
FILTER_FLAG_ENCODE_AMP - Encode the & character to &amp;

Deze FLAG kun je meegeven als je bijv geen quotes wilt encoden (ging idee waarom je dat zou willen)
Of karakters onder een bepaald ASCII getal weg laten. Kijk hiervoor in een ASCII tabel. Daar zie je dat 32 een spatie is en alles daaronder zijn speciale karakters. met STRIP_LOW worden deze karakters dus gestript.

>>> Klopt inderdaad, hij checkt niet of er gepost is, dat kan ik nog wel toevoegen.
Lijkt me wel handig ;)

>>> Wat is dan het voordeel om try catch te gebruiken? Het klinkt een klein beetje als if else, if code is goed = voer uit else = foutmelding.
Dat je een fout opvangt en niet zomaar een vreemde error op je scherm komt. Voor de bezoeker natuurlijk sowieso niet mooi. Jij geeft dan een mooie melding 'Helaas is er wat mis gegaan tijdens het inloggen.' i.p.v. iets wat de bezoeker waarschijnlijk niet begrijpt.
Gewijzigd op 13/03/2014 12:26:10 door Michael -
 
Snelle Jaap

Snelle Jaap

13/03/2014 12:30:20
Quote Anchor link
Oke, is al een stuk duidelijker, ik zag dit stuk ook nog voorbij komen:

if( $ex->getCode() == 23000)
{
$message = 'Username already exists';
}
else
{
/*** if we are here, something has gone wrong with the database ***/
$message = 'We are unable to process your request. Please try again later"';
}
Dan zal dat (23000) wel een error code zijn?
 
Mathieu Posthumus

Mathieu Posthumus

13/03/2014 13:35:01
Quote Anchor link
Haha het is wel vet dat je dit doet maar echt ik snap er helemaal niks van:P
 
Snelle Jaap

Snelle Jaap

13/03/2014 13:38:05
Quote Anchor link
Gewoon goed de comments lezen, en als je iets niet doorhebt, kijk dan even op internet wat iets betekend en bekijk wat voorbeelden. Zo heb ik het gedaan, nog lang niet alles is duidelijk, maar ik kan nu wel een redelijk veilig (?) login script bouwen. Alleen wordt er nog niet gecheckt of er ook echt iets gesubmit/gepost is zoals Michael al zei.
 
Mathieu Posthumus

Mathieu Posthumus

13/03/2014 13:39:09
Quote Anchor link
Aha naja ik zal er wel naar kijken als ik weer op school zit. Dus over een weekje
 
Snelle Jaap

Snelle Jaap

13/03/2014 13:41:17
Quote Anchor link
Het gaat er vooral om dat je weet wat dingen doen, bij mij op school werden er veel dingen geleerd zonder dat je doorhebt wat je aan het doen bent, zo komt het nooit binnen. Op php.net kun je echt bijna alles vinden wat je zoekt.
 
Mathieu Posthumus

Mathieu Posthumus

13/03/2014 13:45:31
Quote Anchor link
Jaap dan kan ik beter kijken op phphulp.nl of w3schools.com want dat is voor meer duidelijker ik vind php.net echt niet duidelijk (Voor mij he!)
 
Snelle Jaap

Snelle Jaap

13/03/2014 13:47:24
Quote Anchor link
Had ik ook in het begin ja, maar je moet kijken naar de examples, als je praktijkvoorbeelden ziet wordt er al een stuk meer duidelijk. Het helpt ook als je even leert wat alle basiswoorden zijn die worden gebruikt op de site, zoals variabelen/parameters etc.
Gewijzigd op 13/03/2014 13:55:12 door Snelle Jaap
 
Mathieu Posthumus

Mathieu Posthumus

13/03/2014 13:54:33
Quote Anchor link
ja das waar
 
Ivo P

Ivo P

13/03/2014 14:27:48
Quote Anchor link
je begint je script, alsof je een nieuwe user wilt gaan inserten in je database.
Dat zeg je ook in de comments op regel 41,

maar dan ga je ineens inloggen.
Het is natuurlijk niet handig om de hacker al direct te vertellen hoe lang een username moet zijn, en welke tekens daarin mogen zitten.

Er is trouwens geen zinnige reden te bedenken waarom een password een max-stringlengte zou moeten hebben en waarom er alleen alnum-tekens in zouden mogen zitten.
Je slaat het toch gehasht op....


Daarnaast moet je dergelijke lengte controles ook uitvoeren op de ge-sanitizede versie

username aap is te kort, maar '<html tags worden straksverwijderd/>aap<nog meer html>'

is lang genoeg als strlen op de invoer, maar na de filter functie blijft "aap" over.


in de query op regel 58 is het niet zinnig om de username en password op te vragen: die heb je niet nodig en staat bovendien al letterlijk in de WHERE regel opgenomen...
 
Snelle Jaap

Snelle Jaap

13/03/2014 14:30:27
Quote Anchor link
Heb je gelijk in, dit script komt samen met een bijna identiek script dat een user insert in de database, vandaar. Bedankt voor je andere punten, ik ga wat punten verbeteren.

>>Er is trouwens geen zinnige reden te bedenken waarom een password een max-stringlengte zou moeten hebben en waarom er alleen alnum-tekens in zouden mogen zitten.
Je slaat het toch gehasht op....

Dat is voor het wachtwoord zelf, in een sha1 encrypted password komen die gewoon voor, dus dat zou toch geen probleem moeten zijn?

En met die max string length doe ik hier geloof ik wat mee: $stmt->bindParam(':phpro_password', $phpro_password, PDO::PARAM_STR, 40); Aangezien een sha1 encryptie 40 tekens is.

Toevoeging op 14/03/2014 11:23:22:

Nog een vraag, ik wil graag die messages weergeven in een bericht op de site zonder refresh, moet ik dan heel m'n script weer omgooien? of is dat best simpel te doen? Kan iemand me daarmee op weg helpen?
Gewijzigd op 13/03/2014 14:43:58 door Snelle Jaap
 
Michael -

Michael -

14/03/2014 11:27:14
Quote Anchor link
Zonder refresh is AJAX. Dan zou het POST gedeelte in een apart bestand moeten doen en met jQuery kun je $.post de juiste data naar de pagina sturen zonder een refresh en de data die je terug krijgt tonen als melding.
 
Snelle Jaap

Snelle Jaap

14/03/2014 11:29:18
Quote Anchor link
Ja ik weet wel een beetje hoe dat werkt, maar heb dat nog nooit in combinatie met PDO gedaan. Als ik het POST gedeelte weghaal kan mijn script het toch niet meer vinden?
 
Michael -

Michael -

14/03/2014 11:31:54
Quote Anchor link
Dat heeft weinig met PDO te maken. Je maakt gewoon een post request met AJAX.
Die POST wordt dan dus afgehandeld door een andere pagina dan waar je het formulier hebt staan.
Als je weet hoe het werkt, probeer het gewoon ;)
 
Snelle Jaap

Snelle Jaap

14/03/2014 11:32:51
Quote Anchor link
Oke, maar is een poging wagen dan.

Toevoeging op 14/03/2014 11:48:30:

Aan het script hoef ik niks meer aan te passen? Het gaat namelijk alleen om validatie, en als alles correct is wil ik het script laten uitvoeren (natuurlijk ook nog even server side valideren)

Toevoeging op 14/03/2014 11:56:33:

Ik maak anders wel een nieuw topic met de code die ik nu heb, is wat overzichtelijker.
 
Michael -

Michael -

14/03/2014 11:59:56
Quote Anchor link
heb je ook naar de punten van Ivo gekeken?
alnum voor een wachtwoord is wat vreemd. Je zou juist graag vreemde karakters willen die je nou niet toestaat. een max lengte (PARAM_STR, 40) op het wachtwoord is niet nodig. en de andere punten van Ivo.
 
Snelle Jaap

Snelle Jaap

14/03/2014 12:05:53
Quote Anchor link
Ja had al gereageerd op z'n reactie, en wat punten worden aangepast.

Toevoeging op 14/03/2014 12:08:42:

Ik heb trouwens een nieuw topic aangemaakt in het Javascript gedeelte.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.