Hallo,

Ik ben net begonnen met php (al wel bekend met andere talen) en wil een inlogsysteem maken met mySQL en met een aanmeld form en een log uit knop. Ik heb al wat geprobeerd maar ik krijg telkens een fout te zien. Dit inlog systeem komt in een webapp dus gebruik ik ook jquery. Het volgende is wat ik al heb:

aanmelden.php:

<html>
    <head>
        <title> Aanmelden </title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="UTF-8">
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css">
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>
		<style>
           .alaangemeld{
             text-align:center;
           } 
           a{
                 text-decoration: none;
           }
           .hier{
                 color: #fbc406;
           }
           
        </style>
	</head>
	<body>
        <h1 style="text-align:center;"> Aanmelden </h1>
        <form action="aanmelden.inc.php" method="post" data-ajax="false">
            <input type="text" name="mail" value="" placeholder="E-mail">
            <input type="password" name="ww" placeholder="Wachtwoord">
            <input type="password" name="wwhh" placeholder="Herhaal wachtwoord">
            <button type="submit" name="signup-verzend">Aanmelden</button>
        </form>
        <br>
        <div class="alaangemeld">
           <p> Al aangemeld? Klik dan <a href="login.php"><span class="hier">hier</span></a></p>
        </div>
	</body>
</html


aanmelden.inc.php:

<?php
session_start();

require "../includes/connect.php"; //hier wordt verbinding gemaakt met de database phpmyAdmin
$errors = 0;
$mail = "";

if(isset($_POST['signup-verzend'])){
    $mail = $_POST['mail'];
    $ww = $_POST['ww'];
    $wwhh = $_POST['wwhh'];


    // checken voor fouten in invoer    
    if(empty($mail)) {
        $errors = $errors + 1;  
    }
    if(empty($ww)) {
        $errors = $errors + 1;
    }
    if(empty($wwhh)) {
        $errors = $errors + 1;
    }
    if($ww !== $wwhh) {
        $errors = $errors + 1;
    }

    if(!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
        $errors = $errors + 1;
    }
    
    //kijken of er al iemand is met dezelfde mail
    $mailQuery = "SELECT * FROM gb WHERE mail=? LIMIT 1";
    $stmt = $conn->prepare($mailQuery);
    $stmt->bind_param('s', $email);
    $stmt->execute();
    $result = $stmt->get_result();
    $mailCount = $result->num_rows;
    $stmt->close();

    if($mailcount > 0){
        $errors = $errors + 1;
    }

    if(count($errors === 0)) {
        $wwSecure = password_hash($ww, PASSWORD_DEFAULT);
        $token = bin2hex(random_bytes(50));
        $verified = false;

        $sql ="INSERT INTO gb (mail, ww, verified, token, ww) VALUES (?, ?, ?, ?)";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param('ssbs', $mail, $verified, $token, $wwSecure);
        
        if($stmt->execute()){
            //log automatisch in
            $gb_id = $connect->insert_id;
            $_SESSION['id'] = $gb_id;
            $_SESSION['mail'] = $mail;
            $_SESSION['verified'] = $verified;

            //een bericht instellen
            header("Location:geslaagd.html");
            exit();

        } else{
            $errors = $errors + 1;
        }
    }else(count($errors > 0)){
        header("Location:signup.php/?error=ErIsIetsFoutIngevuld");
        exit();
    }
 }else{
    header("Location:signup.php");
 }
?>


geslaagd.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p> U bent aangemeld!</p>
</body>
</html>


login.php:


<html>
    <head>
        <title> Inloggen </title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="UTF-8">
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css">
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>
		<style>
           .alaangemeld{
             text-align:center;
           } 
           a{
                 text-decoration: none;
           }
           .hier{
                 color: #fbc406;
           }
           
        </style>
	</head>
	<body>
        <h1 style="text-align:center;"> Inloggen </h1>
        <form action="login.inc.php" method="post" data-ajax="false">
            <input type="text" name="mail" value="" placeholder="E-mail">
            <input type="password" name="ww" placeholder="Wachtwoord">
            <button type="submit" name="signup-verzend">Log in</button>
        </form>
        <br>
        <div class="alaangemeld">
           <p> Nog niet aangemeld? Klik dan <a href="aanmelden.php"><span class="hier">hier</span></a></p>
        </div>
	</body>
</html>


Voor login.inc.php heb ik nog niets en weet ook nog niet hoe dit moet. Ik wil eerst ervoor kunnen zorgen dat je kan aanmelden in de website. Ik heb een tutorial gevolgd op youtube dus het zou kunnen dat ik wat heb overgenomen heb en niet heb verklaard, zou u dit ook kunnen vertellen wat ik zou moeten toevoegen, aanpassen, etc.?

Ik hoop dat u mij snapt en mij kan helpen! Ik zie uw bericht graag!

PS: Ik gebruik PHP versie 7.3 op mijn server met de volgende extensies: bcmath, dom, fileinfo, gd, intl, ioncube_loader, json, mbstring,mcrypt, mysqlnd, nd_mysqli, pdo, pdo_mysql, pdo_sqlite, phar, posix, soap, sockets, xmlwriter, xmlreader, xsl, zip



,groetjes Sem


Wat bedoelt u?
Zie mijn rode modedit ^ en Frank zijn bericht van 20:47.
In principe hoef ik toch niet nog een count voor de errors en dan te zeggen er is een fout. Aangezien er bij elke error al "exit();" wordt gedaan.


<?php
session_start();

require "../includes/connect.php";
$errors = array[]; //errors tellen
$mail = "";

if(isset($_POST['signup-verzend'])){
    $mail = $_POST['mail'];
    $ww = $_POST['ww'];
    $wwhh = $_POST['wwhh'];


    // checken voor fouten in invoer  
    // kijken of e-mail niet leeg is  
    if(empty($mail)) {
        header("Location:../signup.php?error=eMailIsLeeg");
        exit();
    }
    //kijken of wachtwoord niet ingevuld is
    if(empty($ww)) {
        header("Location:../signup.php?error=WachtwoordIsLeeg");
        exit();
    }
    //kijken of wachtwoordherhaal niet ingevuld is
    if(empty($wwhh)) {
        header("Location:../signup.php?error=WachtwoordHerhaalIsLeeg");
        exit();
    }
    //kijken of de twee ww hetzelfde zijn
    if($ww !== $wwhh) {
        header("Location:../signup.php?error=WachtwoordenNietHetzelfde");
        exit();
    }
    //kijken of het een geldig e-mail adres is
    if(!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
        header("Location:../signup.php?error=eMailNietGeldig");
        exit();
    }
    
    //kijken of er al iemand is met dezelfde mail
    $mailQuery = "SELECT * FROM gb WHERE mail=? LIMIT 1";
    $stmt = $conn->prepare($mailQuery);
    $stmt->bind_param('s', $email);
    $stmt->execute();
    $result = $stmt->get_result();
    $mailCount = $result->num_rows;
    $stmt->close();

    //als er meerdere accounts bestaan moet er een error komen
    if($mailcount > 0){
        $errors = $errors + 1;
        header("Location:../signup.php?error=EmailAlBekend");
        exit();
    }
    
    //als er geen fouten zijn bij invoer krijg je een token en ben je dus niet verified 
    if(count($errors) == 0)) {
        $wwSecure = password_hash($ww, PASSWORD_DEFAULT);
        $token = bin2hex(random_bytes(50));
        $verified = false;
    
        //persoon toevoegen aan database
        $sql ="INSERT INTO gb (mail, verified, token, ww) VALUES (?, ?, ?, ?)";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param('ssbs', $mail, $verified, $token, $wwSecure);
        
        if($stmt->execute()){
            //log automatisch in
            $gb_id = $connect->insert_id;
            $_SESSION['id'] = $gb_id;
            $_SESSION['mail'] = $mail;
            $_SESSION['verified'] = $verified;

            //een bericht instellen
            $_SESSION['message'] = "U bent ingelogd!";
            header("Location:../");
            exit();

          //een of andere manier niet gelukt om de gebruiker toe te voegen aan database
        } else{
            header("Location:../signup.php?error=ToevoegenAanDbMislukt");
            exit();
        }
    }
//als je op deze site komt niet via signup.php dan word je naar home gestuurd
}else{
    header("Location:../");
}

?>

Een exit; na een fout?

Stel: Jij bent op visite, en je gooit per ongeluk een vaas om. Loop je dan ook zomaar weg om het huis van je vriend te verlaten? :-D

Nee, exit; is hier NOOIT de oplossing. Je script moet juist NIET stoppen en gewoon netjes doorgaan.

Wel hoort er een exit; na een location-header. Maar location-headers zijn weer niet de oplossing om foutmeldingen te tonen.

- Je verzamelt eerst alle foutmeldingen in je array.
- Je telt deze
- Is het aantal hoger dan 0: "Er is iets niet ingevuld" en toon alle fouten.
Is het aantal 0: Hoera! Alles is goed ingevuld. Ga door met het proces en voeg de data toe.
Ik heb nog een vraag. Ik heb nu namelijk allemaal verwijzingen bij elke error. Dus dan zou de gebruiker moeten kijken in de URL bij een webapp al helemaal onwaarschijnlijk. Hoe kan ik een message laten zien in de signup.php die in de signup.inc.php wordt gevormd?

Als je het onderstaande doet creëer je volgens mij alleen een pop-up in de signup.php, maar deze moet alleen ontstaan als de message nodig is.


function function_alert($message) { 
      
    // Display the alert box  
    echo "<script>alert('$message');</script>"; 
} 



[size=xsmall]Toevoeging op 31/03/2020 10:12:21:[/size]

- Ariën - op 31/03/2020 10:07:42

Een exit; na een fout?

Stel: Jij bent op visite, en je gooit per ongeluk een vaas om. Loop je dan ook zomaar weg om het huis van je vriend te verlaten? :-D

Nee, exit; is hier NOOIT de oplossing. Je script moet juist NIET stoppen en gewoon netjes doorgaan.

Wel hoort er een exit; na een location-header. Maar location-headers zijn weer niet de oplossing om foutmeldingen te tonen.

- Je verzamelt eerst alle foutmeldingen in je array.
- Je telt deze
- Is het aantal hoger dan 0: "Er is iets niet ingevuld" en toon alle fouten.
Is het aantal 0: Hoera! Alles is goed ingevuld. Ga door met het proces en voeg de data toe.


Ooooohhh ik snap hem! Ahh dankuwel. Het is natuurlijk handig om te weten welke fouten je allemaal hebt als je er meerdere hebt. De exit moet dus weg bij alle errors. Maar wat moet er voor in de plaats komen van de
 header("location:/signup.php?error=.....") 

Maar waarom verwijs je dan bij elke error?
Wat is dat de reden van? Het is overigens ook een potentieel risico voor phishing.

Iemand kan een fake-site maken om je logins te onderscheppen, om vervolgens naar www.jouwsite.nl/?error=LogInFout te linken.

De gebruiker ziet dat het fout gaat, maar denkt gelukkig toch op jouw site ingelogd te zijn, wat niet zo is.

Dus geen location-headers, maar je array steeds verder opbouwen. Het stappenplan heb ik al geschreven net.
Het is wel een goede gewoonte om na de validatie en/of verwerking van een POST te redirecten.

Dat zou inhouden dat je de informatie, of in ieder geval zoveel mogelijk informatie, op een of andere manier zult moeten onthouden om deze weer terug in het formulier te plaatsen, dit is ook een stukje gebruiksvriendelijkheid, zodat iemand die een fout maakt niet elke keer alles opnieuw hoeft in te vullen. Dit (onthouden en terugplaatsen) zou je kunnen bewerkstelligen door gebruikmaking van een sessie.

Dit is dus ook een uitgelezen moment om na te gaan denken over de algemene structuur van je webpagina/-applicatie en hoe je hier doorheen navigeert. Vooral wanneer jouw applicatie veel formulieren bevat is het belangrijk -en het bespaart je later ook enorm veel tijd- om dit proces te stroomlijnen.

En als je een aanzienlijke hoeveelheid / heel veel formulieren hebt is het mogelijk zelfs interessant om een apart formuliersysteem te bouwen. Maar soms kan het ook handig zijn om hier geen gebruik van te maken, ingeval het zeer specialistische formulieren betreft, zoals bijvoorbeeld een login- of zoekformulier. Maar die gevallen vormen dan de uitzondering op de regel.

EDIT: ook is het verstandig om na te denken over hoe je informatie structureert in je sessie. Nu stop je "id", "mail" en "verified" los in je sessie, waarom?
"id" zal nodig zijn om een gebruiker te identificeren
"mail" is afleidbaar
"verified" is nogal zinloos (te meer deze waarde false blijft na registratie?), stop gewoon niets in je sessie als er niets "geverifieerd" is, jij hebt de controle over je sessie.

Maar dan wil je niet dat formulierdata "botst" met deze user data, of nog erger, dat je door een hack in je formulier het "id" veld zou kunnen overschrijven ofzo. Je zult dus verschillende segmenten in je sessie moeten creëren. Bijvoorbeeld $_SESSION['form'] als "root" (tis nog steeds geen boom :p) / uitgangspunt voor al jouw formulieren.
>> Als programma gebruik ik nu Visual Studio Code. Wat doet NetBeans dan beter?

Al denk ik misschien van wel, kan het niet hard maken omdat ik Visual Studio Code niet ken (of misschien van heel vroeger). Het punt waarom ik het zei is omdat Netbeans bij mij direct een rode markering liet zien op die else statement.

Met andere woorden zit een goede PHP editor vol vernuft om jou te helpen. En als er dit soort slordigheidjes blijken te zijn dan is het vaak zo dat er geen php editor gebruikt wordt.

[size=xsmall]Toevoeging op 31/03/2020 18:46:44:[/size]

Zoals Arien al verteld heeft moet je een gebruiker juist wijzen op een invoerfout en natuurlijk niet gelijk je programma afbreken. Het voordeel van de fouten toevoegen aan een array is dat je deze dan netjes kunt laten zien aan de gebruikers.


<?php
$errors = [];

if(strlen($mail) == 0) {
    $errors[] = 'U moet een ander email adres opgeven';
}
?>

<!-- ERGENS TUSSEN DE HTML: -->

<!-- controleren of er errors zijn en dan netjes weergeven -->
<?php if(count($errors)): ?>
   <div class="alert alert-warning">
      <ul>
         <?php foreach($errors as $error): ?>
            <li><?php echo $error; ?></li>
         <?php endforeach; ?>
      </ul>
   </div>
<?php endif; ?>
Thomas van den Heuvel op 31/03/2020 16:37:56

Het is wel een goede gewoonte om na de validatie en/of verwerking van een POST te redirecten.

Dat zou inhouden dat je de informatie, of in ieder geval zoveel mogelijk informatie, op een of andere manier zult moeten onthouden om deze weer terug in het formulier te plaatsen, dit is ook een stukje gebruiksvriendelijkheid, zodat iemand die een fout maakt niet elke keer alles opnieuw hoeft in te vullen. Dit (onthouden en terugplaatsen) zou je kunnen bewerkstelligen door gebruikmaking van een sessie.

Dit is dus ook een uitgelezen moment om na te gaan denken over de algemene structuur van je webpagina/-applicatie en hoe je hier doorheen navigeert. Vooral wanneer jouw applicatie veel formulieren bevat is het belangrijk -en het bespaart je later ook enorm veel tijd- om dit proces te stroomlijnen.

En als je een aanzienlijke hoeveelheid / heel veel formulieren hebt is het mogelijk zelfs interessant om een apart formuliersysteem te bouwen. Maar soms kan het ook handig zijn om hier geen gebruik van te maken, ingeval het zeer specialistische formulieren betreft, zoals bijvoorbeeld een login- of zoekformulier. Maar die gevallen vormen dan de uitzondering op de regel.

EDIT: ook is het verstandig om na te denken over hoe je informatie structureert in je sessie. Nu stop je "id", "mail" en "verified" los in je sessie, waarom?
"id" zal nodig zijn om een gebruiker te identificeren
"mail" is afleidbaar
"verified" is nogal zinloos (te meer deze waarde false blijft na registratie?), stop gewoon niets in je sessie als er niets "geverifieerd" is, jij hebt de controle over je sessie.

Maar dan wil je niet dat formulierdata "botst" met deze user data, of nog erger, dat je door een hack in je formulier het "id" veld zou kunnen overschrijven ofzo. Je zult dus verschillende segmenten in je sessie moeten creëren. Bijvoorbeeld $_SESSION['form'] als "root" (tis nog steeds geen boom :p) / uitgangspunt voor al jouw formulieren.


Heel veel informatie om zo in 1 keer te lezen, maar zeker goed te gebruiken dankjewel! Dit ga ik zeker te weten gebruiken ook in de documentatie die ik moet aanleggen bij dit project. Dankuwel!

Frank Nietbelangrijk op 31/03/2020 18:40:01

>> Als programma gebruik ik nu Visual Studio Code. Wat doet NetBeans dan beter?

Al denk ik misschien van wel, kan het niet hard maken omdat ik Visual Studio Code niet ken (of misschien van heel vroeger). Het punt waarom ik het zei is omdat Netbeans bij mij direct een rode markering liet zien op die else statement.

Met andere woorden zit een goede PHP editor vol vernuft om jou te helpen. En als er dit soort slordigheidjes blijken te zijn dan is het vaak zo dat er geen php editor gebruikt wordt.



Oke ik ga het downloaden, bedankt voor de tip! Welke versie van NetBeans kan ik het beste downloaden op de NetBeans site (https://netbeans.apache.org/download/). De Apache NetBeans 11 feature update 3 (NB 11.3) versie?

,groetjes Sem

Reageren