Door
nilix bies
op 05-08-2018 17:44
gewijzigd op 05-08-2018 17:54
7.218 views
Beste iedereen.
Ik hoop dat hier een paar php freaks zijn die mij kunnen helpen
Ik beheer een kleine website voor onze fotoclub. Nu is de webhosting in eens over gegaan naar php7.
Hier door werken enkele scripts niet meer ik heb de meeste weer goed gekregen door aan passingen. Maar net de inlog script voor leden werkt niet meer.
Mijn mysql data base is goed daar worden wel gegeven uit opgehaald op een andere test pagina en voor de portfolio's
Na het inloggen komt er gelijk een fout.
Hier door komt er ook een stuk van het scrip in beeld wat normaal niet zou kunnen
Dit zie ik in beeld staan:
Fout: ingevoerd gebruikersnaam klopt niet!</p>";
}else{ //mailadres staat in de database, we gaan verder!
while($record = mysqli_fetch_object($ophalen)){
$password_db = $record->wachtwoord;
}
---------------------------------------
Ik weet niet of het nu wel mag maar hier onder mijn script wat is er fout?
<?
session_start();
if ($_POST['submit']=="login")
{
include "log.php";
$con, het eerste argument van de mysqli_query() functie, is nu een verplicht argument. Deze variabele $con zou het object moeten bevatten wat het (geslaagde) resultaat is van het maken van een verbinding met je database.
Tenzij $con zit verstopt in log.php of er nog meer code wordt geladen dan dat hierboven staat beschreven is deze variabele ongedefinieerd, wat tot gevolg heeft dat je ook niet kunt communiceren met je database omdat je mysqli_query() functie je database niet kent.
Om dit te laten werken zul je dus moeten zorgen dat $con verwijst naar het object wat je database-connectie representeert.
[size=xsmall]Los daarvan stemt het bovenstaande fragment mij niet erg gerust op een waterdicht loginsysteem, oftewel, deze is waarschijnlijk zo lek als een mand. Maar dit interesseert niemand waarschijnlijk een biet, we zijn hier per slot van rekening alleen maar om vragen te beantwoorden, niet om adviezen te geven en mensen de goede kant op te sturen nietwaar.[/size]
- Verander $_POST['submit'] == "login" liever in if($_SERVER['REQUEST_METHOD'] == 'POST')
- Initialiseer variabelen buiten de if statements als je ze verderop in je code wilt gebruiken
- Filter variabelen uit een formulier. De deur voor inbrekers staat nu wagenwijd open!
- bedoelde je een = in plaats van een == bij $gebrnaam == (strtolower($_POST['gebruikersnaam']));
- Het gebruik van backticks wordt afgeraden in je database queries
- Gebruik logische variabelnamen. $ophalen is onjuist omdat je van mysqli_query een resultaat verwacht. Het daadwerkelijk ophalen van de data doe je als je gaat fetchen
- Je echo't direct de foutmeldingen. Dit leidt tot ongeldige HTML omdat ze niet netjes in de <body> van je pagina zullen komen. Je zult deze eerst in een variabele moeten zetten om ze verderop in je code (de view) alsnog tussen je html te plaatsen
- Je slaat wachtwoorden niet op in de database. In plaats daarvan moet je de wachtwoorden versleutelen en de sleutel in de database opslaan. Vandaag de dag doe je dat het beste met BCrypt (http://php.net/manual/en/function.password-hash.php)
- Waarom een while($record = mysqli_fetch_object($result)) als je hooguit 1 record verwacht?
- Waarom een tweede keer fetchen?
- Onnodig kopieren van variabelen en telkens rechtstreeks $_POST variabelen benaderen zonder te filteren
- Redirecten doe je met header('Location: adm.php?idlog=' . $gebrnaam)
- Waarom query parameter idlog gebruiken. Dit kan elke idioot wijzigen. Waarom haal je dat niet uit de sessie?
- De datenu kolom zou je van het type DATETIME moeten maken, vervolgens sla je de datum op met $datenu = date('Y-m-d');
- Lijkt mij tevens ook veiliger en logischer om om aan de tabel 'leden' een kolom 'isAdmin' toe te voegen waarbij je bij een admin een 1 in de kolom plaatst en bij normale leden een 0. En dan bepaal je vervolgens aan de hand van de waarde van die kolom of het een admin betreft of niet.
- Je zou ipv de gebruikersnaam het 'id' (of 'user_id') of iets dergelijks in de sessie moeten opslaan. Deze kolom is als het goed is aangemaakt als 'primary key'. Dit zoekt sneller en je krijgt gegarandeerd het juiste record.
<?php
// initialiseer variabelen
$gebrnaam = '';
$errors = []; // lege array
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
include "log.php";
// laten we kijken of de benodigde POST variabelen ook bestaan...
if(!array_key_exists('gebruikersnaam', $_POST) || !array_key_exists('wachtwoord', $_POST)) {
$errors[] = 'Fout bij het verwerken van het formulier';
} else {
$gebrnaam = strtolower(mysqli_real_escape_string(trim($_POST['gebruikersnaam'])));
$sql = "SELECT * FROM leden WHERE gebruikersnaam = '" . $gebrnaam . "'";
$result = mysqli_query($con, $sql);
$aantal = mysqli_num_rows($result); // aantal records met verstuurd emailadres tellen
if ($aantal == 0)
{
$errors[] = 'Fout: ingevoerd gebruikersnaam klopt niet!';
}
else
{
//mailadres staat in de database, we gaan verder!
$record = mysqli_fetch_object($result);
$password_db = $record->wachtwoord;
//passwordsleutel nu vergelijken met de sleutel van het ingevoerde password
if ($password_db != password_hash($_POST['wachtwoord'], PASSWORD_DEFAULT))
{
$errors[] = 'Verkeerd wachtwoord!';
}
else
{
//email staat in database en password klopt, sessie starten!
session_start();
$_SESSION['idlog'] = $gebrnaam;
if ($gebrnaam == "admin")
{
header('Location: adm.php');
exit;
}
else
{
$datenu = date('Y-m-d');
mysqli_query($con, "UPDATE leden SET datenu='" . $datenu . "' WHERE gebruikersnaam='" . $gebrnaam . "'");
header('Location: loginstart.php');
exit;
}
}
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<?php if(count($errors)): ?>
<ul class="errors">
<?php foreach($errors as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<form method="post">
<input type="text" name="gebruikersnaam" value="<?php echo htmlspecialchars($gebrnaam); ?>"> <!-- escape ook altijd je output -->
<input type="password" name="wachtwoord">
<button>Login</button>
</form>
</body>
</html>
[size=xsmall]Toevoeging op 05/08/2018 20:08:20:[/size]
Voordat je met mijn voorbeeld gaat werken zul je de volgende zaken moeten begrijpen:
- wachtwoorden
Alle gebruikers wachtwoorden in de database zul je eenmalig moeten omzetten naar sleutels.
Dit zou je kunnen doen door een script te schrijven die dat voor je doet, of je maakt een script die je de sleutel van een wachtwoord laat zien en plakt de sleutel handmatig bij de juiste gebruiker in de tabel:
<?php
echo password_hash('geheimpje', PASSWORD_DEFAULT);
?>
- de header() functie
Je kunt de header functie alleen gebruiken als je script nog geen enkele output gegenereerd heeft.
Er mag dus nog geen echo gedaan zijn of een blok HTML verzonden zijn
- de view
Een goede gewoonte is om bovenaan je php script te schrijven waarin je geen enkele output genereert maar in plaats daarvan alles nog even in variabelen op te slaan. Je kunt dan nog alle kanten op. Onderaan doe je de HTML met daartussen kleine php blokken die enkel bedoeld zijn om variabelen te echo-en. Je komt zo nooit in de problemen en je code is veel beter leesbaar
- gebruik een goede php editor
- escape ook altijd onveilige variabelen voordat je deze echo't
Frank dank je wel voor deze duidelijke uitleg. Ik ga er mee aan de slag.
Ben al jaren niet meer zo thuis in het programmeren. En stiekem verandert er veel in.. Te veel om bij te houden..
Gelukkig zijn er altijd mensen die wel al deze veranderingen gelijk snappen en weten hoe het werkt.
Ik ga er mee aan de slag en kijken of het lukt..
Tot zo ver heel vriendelijk bedankt.
Eigenlijk zou ik ook aanraden om niet twee foutmeldingen te maken voor een fout wachtwoord en een foute username. Ik zou dan liever zeggen dat de gebruikersnaam of wachtwoord fout is.
Ik ben er al mee bezig en toch wel makkelijk dat je de foutmeldingen apart kan zien..
Loop nu in het begin al vast.
Krijg nu de melding Fout: ingevoerd gebruikersnaam klopt niet!
Zeker weten dat de gebruikersnaam in de mysql staat.
En deze ook goed word aan geroepen. Op andere delen van de site staan portfolios van leden en deze roepen via de zelfde. log.php de mysql aan om informatie op de site te plaatsen en hier werkt het wel..
Lijkt me dat de mysql aanroep goed is .. Maar in het script nog iets niet goed doe.