Jasper Schellekens op 30/03/2015 18:04:40

Beste scripters!

Ik ben beginnend met PHP.
Ik wil dus op mijn website een blokkade maken voor dubbel login.

Hoe wil ik dit doen?
In de tabel users heb ik online en online2.
online registreert wanneer de klant inlogt( tijdstip datum etc.)
Bij online2 komt na het inloggen inplaats van nee, ja te staan.

Op het moment dat een klant inlogt op mijn website verandert dit.
Nu wil ik zorgen dat de klant niet met een tweede scherm kan inloggen (dubbel login)

Hoe maak ik bij het inloggen iets dat controleert of online2 op ja of nee staat?
Staat die op ja? dan wil ik de foutmelding 'u bent al ingelogd' laten zien.
Staat er nee? dan kan er ingelogd worden.

Hoe kan ik dit doen?

De bestanden mocht het nodig zijn:

login.php
<?php /* ------------------------- */
include("config.php");
if(isset($_POST['login'])) {
$dbres = mysql_query("SELECT * FROM `users` WHERE `login`='{$_POST['login']}' AND `pass`=MD5('{$_POST['pass']}')");
$num = mysql_num_rows($dbres);
if($num > 0) {
$naam = $_POST['login'];
$_POST['login'] = $naam;
$pass = $_POST['pass'];
$_POST['pass'] = $pass;
setcookie("login",'',time()-24*60*60,"/","");
setcookie("validate",'',time()-24*60*60,"/","");
$_SESSION['IP'] = $_SERVER['REMOTE_ADDR'];
$dbres = mysql_query("SELECT *,UNIX_TIMESTAMP(`signup`) AS `signup` FROM `users` WHERE `login`='{$_SESSION['login']}'");
$_SESSION['data'] = mysql_fetch_object($dbres);
if($data->vakantie > 0){
header("Location: $sitelink/index.php?vakantie");
exit;
}
header("Location: inlogger.php?x={$_POST['login']}&pass={$_POST['pass']}");
}
else{
header("Location: $sitelink/index.php?error");
}
}
else if($_GET['x'] == "logout") {
mysql_query("UPDATE `[users]` SET `online`='0000-00-00 00:00:00' WHERE `login`='{$data->login}'");
mysql_query("DELETE FROM `[online]` WHERE `login`='{$_COOKIE['login']}' AND `validate`='{$_COOKIE['validate']}' AND `IP`='{$_SERVER['REMOTE_ADDR']}'");
setcookie("login",'',time()-24*60*60,"/","");
setcookie("validate",'',time()-24*60*60,"/","");
session_destroy();
header("Location: $sitelink/index.php");
}
/* ------------------------- */ ?>


inlogger.php

<?
include("config.php");
$user1 = mysql_query("SELECT * FROM `users` WHERE `activationcode`='0' AND `login`='{$_GET['x']}' AND `pass`=MD5('{$_GET['pass']}')");
$user = mysql_num_rows($user1);
if($user > 0){
$_SESSION['login'] = $_GET['x'];
$data->login = $_GET['x'];
header("Location: index.php?a=loggedin");
}
else{
header("Location: $sitelink/index.php?error");
}
?>

loggedin.php
<table width="100%">
<tr>
<td align="center">
<br><br><br><br>
<table class="div_popup" align="center">
<tr>
<td>
Je bent ingelogd in het systeem en zal over enkele ogenblikken door worden gestuurd. </td>
</tr>
<tr>
<td>
<br><br>
<a href="<? echo $sitelink;?>/v3/index.php?a=news" class="msg_ok">Klik hier indien je niet automatisch verder gaat.</a>
</td>
</tr>
</table>
</td>
</tr>
</table>

<script language="javascript">
setTimeout("document.location.href='<? echo $sitelink;?>/v3/index.php?a=news'",(1000*2));
</script>
</div>
</td>
</tr>

</table>
</td>

Alvast bedankt!

[size=xsmall]Toevoeging op 30/03/2015 18:08:41:[/size]

Kleine edit: De foutmelding is niet nodig die zit er al bij.
Hij moet alleen het dubbel inloggen blokkeren


[size=xsmall]Toevoeging op 30/03/2015 18:42:12:[/size]

Jasper Schellekens op 30/03/2015 18:40:40

[quote="Jasper Schellekens op 30/03/2015 18:04:40"]
Beste scripters!

Ik ben beginnend met PHP.
Ik wil dus op mijn website een blokkade maken voor dubbel login.

Hoe wil ik dit doen?
In de tabel users heb ik online en online2.
online registreert wanneer de klant inlogt( tijdstip datum etc.)
Bij online2 komt na het inloggen inplaats van nee, ja te staan.

Op het moment dat een klant inlogt op mijn website verandert dit.
Nu wil ik zorgen dat de klant niet met een tweede scherm kan inloggen (dubbel login)

Hoe maak ik bij het inloggen iets dat controleert of online2 op ja of nee staat?
Staat die op ja? dan wil ik de foutmelding 'u bent al ingelogd' laten zien.
Staat er nee? dan kan er ingelogd worden.

Hoe kan ik dit doen?

Ik heb het hiermee geprobeert maar helaas werkte dit niet:
<?
include("config.php");
$user1 = mysql_query("SELECT * FROM `users` WHERE `online2`='nee' AND `login`='{$_GET['x']}' AND `pass`=MD5('{$_GET['pass']}')");
$user = mysql_num_rows($user1);
if($user > 0){
$_SESSION['login'] = $_GET['x'];
$data->login = $_GET['x'];
header("Location: index.php?a=loggedin");
}
else{
header("Location: $sitelink/index.php?error");
}
?>


De bestanden mocht het nodig zijn:

login.php
<?php /* ------------------------- */
include("config.php");
if(isset($_POST['login'])) {
$dbres = mysql_query("SELECT * FROM `users` WHERE `login`='{$_POST['login']}' AND `pass`=MD5('{$_POST['pass']}')");
$num = mysql_num_rows($dbres);
if($num > 0) {
$naam = $_POST['login'];
$_POST['login'] = $naam;
$pass = $_POST['pass'];
$_POST['pass'] = $pass;
setcookie("login",'',time()-24*60*60,"/","");
setcookie("validate",'',time()-24*60*60,"/","");
$_SESSION['IP'] = $_SERVER['REMOTE_ADDR'];
$dbres = mysql_query("SELECT *,UNIX_TIMESTAMP(`signup`) AS `signup` FROM `users` WHERE `login`='{$_SESSION['login']}'");
$_SESSION['data'] = mysql_fetch_object($dbres);
if($data->vakantie > 0){
header("Location: $sitelink/index.php?vakantie");
exit;
}
header("Location: inlogger.php?x={$_POST['login']}&pass={$_POST['pass']}");
}
else{
header("Location: $sitelink/index.php?error");
}
}
else if($_GET['x'] == "logout") {
mysql_query("UPDATE `[users]` SET `online`='0000-00-00 00:00:00' WHERE `login`='{$data->login}'");
mysql_query("DELETE FROM `[online]` WHERE `login`='{$_COOKIE['login']}' AND `validate`='{$_COOKIE['validate']}' AND `IP`='{$_SERVER['REMOTE_ADDR']}'");
setcookie("login",'',time()-24*60*60,"/","");
setcookie("validate",'',time()-24*60*60,"/","");
session_destroy();
header("Location: $sitelink/index.php");
}
/* ------------------------- */ ?>


inlogger.php

<?
include("config.php");
$user1 = mysql_query("SELECT * FROM `users` WHERE `activationcode`='0' AND `login`='{$_GET['x']}' AND `pass`=MD5('{$_GET['pass']}')");
$user = mysql_num_rows($user1);
if($user > 0){
$_SESSION['login'] = $_GET['x'];
$data->login = $_GET['x'];
header("Location: index.php?a=loggedin");
}
else{
header("Location: $sitelink/index.php?error");
}
?>

loggedin.php
<table width="100%">
<tr>
<td align="center">
<br><br><br><br>
<table class="div_popup" align="center">
<tr>
<td>
Je bent ingelogd in het systeem en zal over enkele ogenblikken door worden gestuurd. </td>
</tr>
<tr>
<td>
<br><br>
<a href="<? echo $sitelink;?>/v3/index.php?a=news" class="msg_ok">Klik hier indien je niet automatisch verder gaat.</a>
</td>
</tr>
</table>
</td>
</tr>
</table>

<script language="javascript">
setTimeout("document.location.href='<? echo $sitelink;?>/v3/index.php?a=news'",(1000*2));
</script>
</div>
</td>
</tr>

</table>
</td>

Alvast bedankt!

[size=xsmall]Toevoeging op 30/03/2015 18:08:41:[/size]

Kleine edit: De foutmelding is niet nodig die zit er al bij.
Hij moet alleen het dubbel inloggen blokkeren

[/quote]

Je kan wel een tweede login blokkeren, maar wat nu als iemand zijn cookies wist? Dan kan hij niet meer inloggen, en heeft hij zich buitengesloten.

Een tijdslimiet is de beste oplossing. Bij de bron aanpakken dus, de login is hier de bijzaak.

Over de beveiliging:
Het wachtwoord, deze wordt plain text in de URL gezet, en is zichtbaar in je browser. Een dikke no-go dus.

Verder is er ook een berg aan SQL-injecties mogelijk, zou erg rottig zijn dat iemand hierdoor de wachtwoorden van je leden bij elkaar hackt en deze brute-forced. Dan gaan je bezoekers je opeens jouw site niet meer fijn vinden.

Mijn advies: Neem het script grondig onder de loep.
En BTW Aar C,

De passwords kunnen onmogelijk achterhaald worden omdat ze md5 encrypted zijn.

[size=xsmall]Toevoeging op 31/03/2015 00:49:50:[/size]

Je snapt niet dat het niks met cookies te maken heeft.
Het veld online2 verandert pas weer nadat er op uitloggen is geklikt.
Sorry, MD5 is al lang achterhaald. Bruteforce, dictionairy attacks.... het kan allema a l.
Gebruik liever password_hash en password_verify.


En wat als iemand zijn cookies wist? Dan is hij uitgelogd en staat online2 nog op inlogd, en kan hij niet meer inloggen.
EDIT: Sorry ik zie nu dat het wel met cookies werkt.
Hoe kan ik dit dan met de tijd doen?


[size=xsmall]Toevoeging op 31/03/2015 00:56:49:[/size]

Aar C op 31/03/2015 00:52:43

En wat als iemand zijn cookies wist? Dan is hij uitgelogd en staat online2 nog op inlogd, en kan hij niet meer inloggen.



Inderdaad, daarom werkte dit niet:

$user1 = mysql_query("SELECT * FROM `users` WHERE `online2`='nee' AND `login`='{$_GET['x']}' AND `pass`=MD5('{$_GET['pass']}')");
Zie stap 3 die ik genoemd heb. ;)

.
Jasper Schellekens op 30/03/2015 23:56:49
Nee het zit zo.
Het is een soort spel. op dat spel kunnen ze iets kopen in een shop.
Als ze een paar schermen te gelijk open hebben, laten we zeggen 4x, (4x ingelogd in 4 tabladen dus), dan kopen ze hetzelfde item in 4 schermen als ze snel klikken en dan hebben ze het voor de kosten van 1 product.
Dit verkopen ze weer en zo 'hacken' ze geld.

Dit sterkt mij in het vertrouwen dat het gebruik van transacties toch, en nog steeds, de (enige) goede oplossing is.

Tenzij je overal waarden naartoe aan het kopieren bent, je moet wel al je administratie via de database regelen... Als hier sprake van is (je kopieert vanalles overal naartoe, bijvoorbeeld een saldo dat je in je sessie zet ofzo...) dan is je code gewoon brak en kun je beter opnieuw beginnen.
Ik heb iets geprobeert en dat is gelukt het werkt nu.
Alleen zit ik een beetje ermee over die sql injection waar Aar C het over had.
Zou zoiets als dit werken?

{
if(eregi($foutbezig,$locatie))
{
echo "Internet fout, ip adres doorgegeven aan domein houder.";
mail("emailadre","Mysql Injection","Mysql Injection
IP-Adres: $_SERVER[REMOTE_ADDR]","From: Company<emailadres>");
exit();
}
}

Ik kwam het tegen ergens, geen idee of het echt met sql injection te maken heeft.
T is gewoon een vraag.
En hoe kan ik anders een injection blokken?
Het is meer een detectie, als het kwaad al is geschied. Verder is eregi() ook een oude functie die omgebouwd moet worden naar preg_match.

Als je SQL-injection wilt tegengaan, kijk dan vooral naar mysqli_real_escape_string(), ervan uitgaande dat je ook de MySQLi-functies gebruikt. Als de de object-georiënteerde manier gebruikt, is het $mysqli->real_escape_string().
Zie ook: http://php.net/manual/en/mysqli.real-escape-string.php
Thomas van den Heuvel op 31/03/2015 00:59:09


Dit sterkt mij in het vertrouwen dat het gebruik van transacties toch, en nog steeds, de (enige) goede oplossing is.


Wat hebben transacties in deze context voor toegevoegde waarde?
Transacties zijn database-sessie afhankelijk, verschillende tabbladen === verschillende database-sessies.

Ger van Steenderen op 01/04/2015 20:34:12
Wat hebben transacties in deze context voor toegevoegde waarde?

Well...
Het nadeel is dat spelers een gat hebben gevonden om zeg maar te hacken.
Als ze dubbel inloggen en snel klikken dan krijgen ze het 2/3 misschien zelfs 10 keer voor de prijs van 1.

Is dat niet haast een 1:1 schoolvoorbeeld [1] waarbij (soortgelijke) sets handelingen meerdere keren (tegelijkertijd) herhaald worden en er een zodanige verweving plaatsvindt zodat dit een ongewenst effect heeft?
Als je transacties gebruikt zorg je ervoor dat zo'n set (=één sessie) een ondeelbaar geheel wordt. Er vindt dan géén verweving plaats en je administratie blijft dan kloppen. Sure, je kunt dan nog steeds 100x tegelijkertijd een script aanroepen, maar de set wordt dan 100x na elkaar uitgevoerd (de ene set wacht tot de andere klaar is) en de toestand van het systeem zou na afloop nog steeds moeten kloppen. Of de transacties worden op den duur afgekapt omdat je gewoon blut bent, dan moet je maar niet 200x een knop spammen :). Maar dat klopt dan nog steeds, in die zin dat er niet uit het niets ineens valuta wordt gecreëerd, en een aankoop mislukt omdat je onvoldoende valuta hebt...

[1] Dit wordt min of meer beschreven in de laaste alinea van deze paragraaf.

Het verbaast mij dat ik dit (aan jou) moet uitleggen?

EDIT: sterker nog, waarschijnlijk leven de "database-sessies" alleen tijdens het uitvoeren van het script en zijn daarna weg (heeft dus niet eens iets met tabs te maken). Tenzij je wellicht persistente connecties gebruikt, geen idee hoe de situatie dan is.

Reageren