[PHP] Simpel inlogsysteem met list.txt

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • borstel
  • Registratie: Juli 2004
  • Laatst online: 08-07 18:53
Probleem
Ik zit momenteel met een klein php probleempje, waar ik niet helemaal uit kom. Ik heb een simpel inlogscript gemaakt gebaseerd op een list.txt lijst met naam/wachtwoord en cookies.

Het inloggen gebeurt met een simpel formulier, waarna deze 'action.php' wordt aangeroepen. Deze zoekt in list.txt een naam/wachtwoord, wanneer deze is gevonden wordt er een cookie aangemaakt en kun je naar de secure pagina's komen.

Wanneer je een foute naam/wachtwoord combinatie invult, krijg je een echo met 'Log-in failed!'. Echter wil ik dit stukje vervangen door een nieuwe pagina. ( header("Location: login.php?=failed"); ) Wanneer ik dat op deze plek zet, gaat hij altijd naar de login.php?=failed pagina. Ook wanneer je een correct wachtwooord invult, wel wordt er een cookie aangemaakt en kun je op de secure pagina komen. Hij slaat de eerste 'header location' over en gaat dus niet automatisch naar de goede secure pagina.


Ik zit dus te worstelen hoe ik een 'else' kan inbouwen zodat hij alleen met een foute combinatie naar de login.php?=failed pagina gaat. En niet zoals nu... altijd. Ook al is je wachtwoord goed of fout.

Dit is deels gelukt, maar dan werkt het alleen met een gebruikersnaam/wachtwoord die onderin in de list.txt staat. Gebruikersnaam/wachtwoord combinaties bovenin de list.txt maken wel een cookie aan, maar zorgen ervoor dat je altijd naar de login.php?=failed pagina gaat.

list.txt
code:
1
2
3
user1||pass1||
user2||pass2||
enz...


PHP:
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
<?php
if ($_SERVER['REQUEST_METHOD']=="POST"){

$Logi = file("users/list.txt");
co
$size = sizeof($Logi);

foreach($Logi as $Key => $Val)
{ $Data[$Key] = explode("||", $Val); }

for($K = 0; $K<$size; $K++)
{
$user = $Data[$K][0];
$pass =  $Data[$K][1];

if ($user == trim(addslashes($_POST["user"])) && $pass == trim(addslashes($_POST["pass"])) )
{
    setcookie("id", 1, time()+3600);
    header("Location: welcome_secure.php");
}

}
    echo "Log-in failed!"; 
}
?>


Foute/niet werkende oplossing (uitleg hieronder)
PHP:
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
<?php
if ($_SERVER['REQUEST_METHOD']=="POST"){

$Logi = file("users/list.txt");

$size = sizeof($Logi);

foreach($Logi as $Key => $Val)
{ $Data[$Key] = explode("||", $Val); }

for($K = 0; $K<$size; $K++)
{
$user = $Data[$K][0];
$pass =  $Data[$K][1];

if ($user == trim(addslashes($_POST["user"])) && $pass == trim(addslashes($_POST["pass"])) )
{
setcookie("id", 1, time()+3600);
header("Location: welcome_secure.php");

}else{
header("Location: login.php?=failed");
}
}
}
?>

^^ Werkt alleen user2 met inloggen/redirecten naar de secure page. User1 maakt wel een cookie aan, maar redirect niet goed naar de secure pagina, en gaat naar de 'failed' pagina.

Ik hoop dat jullie mijn probleem een beetje begrijpen, anders leg ik het graag nog eens uit.

Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Waar hoort mijn topic? ;)

Klein tikje naar de buren dus.

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:15

Janoz

Moderator Devschuur®

!litemod

Begin eens met je code goed in te laten springen. Ga daarna regel voor regel eens door je code heen lopen om te kijken wat er nu exact gebeurt. Hou daarbij in je achterhoofd dat het script, na een header melding, gewoon doorgaat.

Als ik zo naar het gedrag van je script kijkt verwerkt de browser enkel de eerste redirect die hij binnen krijgt.


Los van dit probleem zie ik ook nog een aantal andere dingen. Waarom doe je addslashes?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 19-09 15:19
Even een sidenote: Als ik /users/list.txt open kom ik bij alle gebruikersnamen en wachtwoorden? Ik zou sowieso md5/sha1 oid erover heen gooien (over de wachtwoorden) alvorens je ze opslaat.

En als ze ingelogd zijn set je een cookie met een id=1 en dan zijn ze ingelogd? Niet héél veilig.

Het beste is een systeem maken die een userID opslaat en een sessieID. Met die SessieID kun je zien welke gebruiker er aan hangt. Maar goed, moet je maar even zoeken.

En na een Header('Location:blaat'); is een exit aan te bevelen. Anders blijft hij het script uitvoeren.

[ Voor 10% gewijzigd door RedHat op 10-06-2009 11:00 ]


Acties:
  • 0 Henk 'm!

  • SlinkingAnt
  • Registratie: December 2001
  • Niet online
De 2de oplossing is een werkende oplossing, maar het inloggen werkt alleen als de user/pass-combinatie op de laatste regel in je list.txt staat?

Op regel 11 start je een for()-loop welke elke regel van het tekstbestand doorloopt, en elke keer de 'header'-aanpast indien deze goed/fout is.

Als op regel 2 een goed antwoord staat, dan word de header op 'OK' gezet, maar op de volgende regel weer op 'FOUT' gezet.

En nu zelf de oplossing bedenken, oftewel met 'break' of een extra variabele :)
RedHat schreef op woensdag 10 juni 2009 @ 11:00:
En na een Header('Location:blaat'); is een exit aan te bevelen. Anders blijft hij het script uitvoeren.
Die dus, alleen 'exit;' bij een succesvolle login, anders kan alleen de user op regel1 inloggen ;)

[ Voor 24% gewijzigd door SlinkingAnt op 10-06-2009 11:06 . Reden: Quote toegevoegd ]

Intel C2Q 9450@3.3 | Gigabyte P35-DS4 | Sapphire R280x | 4x 2GiB PC6400 Kingston DDR2 | 1x Intel 320SSD 240GB | 2x Spinpoint F1 320GiB


Acties:
  • 0 Henk 'm!

  • Manuel
  • Registratie: Maart 2008
  • Laatst online: 19-09 11:12
Inderdaad @SlinkingAnt, dat viel mij zojuist ook reeds op, hij krijgt namelijk dubbele output. Het script checkt wie de laatste gebruiker is, die heeft alleen toegang.

@TS
Je kan dit heel simpel oplossen, je krijgt namelijk standaard twee array's uitgegooid door jou foreach loop, misschien is het handiger om daarmee te gaan werken in plaats van deze for loop.

Acties:
  • 0 Henk 'm!

  • borstel
  • Registratie: Juli 2004
  • Laatst online: 08-07 18:53
RedHat schreef op woensdag 10 juni 2009 @ 11:00:
Even een sidenote: Als ik /users/list.txt open kom ik bij alle gebruikersnamen en wachtwoorden? Ik zou sowieso md5/sha1 oid erover heen gooien (over de wachtwoorden) alvorens je ze opslaat.
Klopt, maar deze is voor afgeschermd met een .htaccess bestand. Ik wil eigenlijk eerst een simpele versie werkend hebben, voordat ik hem verder ga uitbouwen. Ben niet zo'n scripter...

Inspringen leest inderdaad wat makkelijker, dus ga ik ook doen.. is de code wat beter te volgen.

@: SlinkingAnt

De tweede optie werkt inderdaad. Als ik een break toevoeg bij een goeie log-in kan inderdaad alleen de eerste in de lijst inloggen. De rest krijgt een error. Zou je me een klein beetje de goede richting in kunnen helpen? Een extra variabele? Of een break functie ertussen, wanneer hij een goeie log-in heeft gevonden in de lijst, hij stopt met de loop?

Het is niet een heel veilig script, maar het moet simpel werken. Veel script die ik online tegenkom zijn met en MySQL database voor de gebruikers. Maar heb geen database tot m'n beschikking, dus vandaar dat ik het op deze manier probeer op te lossen. Wellicht in de toekomst verder uitbouwen/veiliger maken... Verder is het een kleine website, met weinig bezoekers.

Acties:
  • 0 Henk 'm!

  • Manuel
  • Registratie: Maart 2008
  • Laatst online: 19-09 11:12
Ik denk dat je dan beter niet meer met een tekst bestand kunt werken maar dat je dan eerder met een array gaat werken, zo kan je mooi alles bijhouden en hoef je alleen maar de array te bewerken, hieronder staat een klein voorbeeld:

PHP:
1
2
3
4
5
6
7
$login = array("gebruiker1" => array("wachtwoord1"), "gebruiker2" => array("wachtwoord2"), "etc.");

if(isset($_POST["user"], $_POST["pass"]) && in_array($_POST["user"], $login) && in_array($_POST["pass"], $login[$_POST["user"]])) {
        header("Location: goedelogin.php.dit");
} else {
        header("Location: foutelogin.php.dit");
}


Hierboven heb ik even snel een voorbeeld getypt, er zijn 1000'en manieren hoe je dit kan aanpakken, alleen denk ik dat het beter zo kan (natuurlijk wel de wachtwoorden hashen).

PS: Ik heb het script niet getest :+

Acties:
  • 0 Henk 'm!

  • borstel
  • Registratie: Juli 2004
  • Laatst online: 08-07 18:53
Inderdaad, een stuk makkelijker. Maar het zijn 60 verschillende logins dus een .txt vullen was net even iets sneller. Makkelijk zou zijn als deze werkt, anders ga ik verder met alles in een array+cookie, voor de login.

Of ombouwen naar array+sessie.

Acties:
  • 0 Henk 'm!

  • Noork
  • Registratie: Juni 2001
  • Niet online
Inlezen van de txt en omzetten naar array kan natuurlijk ook. zie b.v.: http://www.php.net/fgetcsv
Pagina: 1