Simple Auth Class

Door Mark Pieper, 20 jaar geleden, 5.750x bekeken

Simpele Auth Class

Benodigdheden:
+ PHP5
+ PDO (Eventueel aan te passen)
+ PHP-kennis (deze class maakt alleen het maken van een inlogsysteem makkelijker)
+ MySQL Database (dit script heeft 1 tabel nodig, sql dump is meegeleverd)

Functies:
+ login(username, wachtwoord) Inloggen met de gebruikersnaam en wachtwoord als parameters
+ logout() Uitloggen
+ isLoggedIn() Returnt een boolean of de gebruiker is ingelogd
+ getId Returnt het id van de ingelogde gebruiker (indien aanwezig)
+ getName Returnt de gebruikersnaam van de ingelogde gebruiker (indien aanwezig)

Veiligheid:
+ Wachtwoord wordt niet opgeslagen, in sessie / cookie
+ Wachtwoord gehasht opgeslagen in de database
+ Controle op IP
+ Controle op User-Agent
+ Maar 1 gebruiker tegelijk op 1 account

Opmerkingen:
+ Dit is dus geen compleet inlog systeem, de inlog formulieren, wachtwoordherstel functie, en registratie functie zul je zelf nog moeten maken.

Gebruik:
+ Voer de sql uit het bestand 'auth.sql' uit in de database
+ Wijzig 'const COOKIE_DOMAIN' op regel 12 van 'Auth.php' naar jouw domein
+ Voeg een nieuwe gebruiker toe in de database, hash het wachtwoord wel eerst met sha1().
+ Bouw het in jouw script in, bekijk ook het voorbeeld: index.php.

Gesponsorde koppelingen

PHP script bestanden

  1. simple-auth-class

 

Er zijn 22 reacties op 'Simple auth class'

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
TJVB tvb
TJVB tvb
20 jaar geleden
 
0 +1 -0 -1
Ik vraag me nogal af hoe veilig dit is. De gegevens worden in een cookie opgeslagen. Voor een hacker zal het heel snel duidelijk zijn dat het een sha1 is. Als die dan 1 keer bruteforced is het heel snel duidelijk hoe het werkt. En dan kan die dus als iedereen inloggen.
Lode
Lode
20 jaar geleden
 
0 +1 -0 -1
@TJVB
Dat doet hij juist relatief goed. Alleen 365 dagen is misschien een beetje lang.
Er worden alleen geen nieuwe hashes e.d. aangemaakt om de x tijd bij een bezoek bijvoorbeeld. bij sessions hebben ze daar session_regenerate_id(); voor bedacht.
En dan heb je nog allerlei andere truukjes als salt's e.d.

Maar er staan gelukkig in ieder geval geen wachtwoorden en login namen in!
Dat is al een heel groot plus punt! Ik zie bijna dagelijks HEEL veel slechtere login/auth's ongeveer...
(Deze site bewaard wel je wachtwoord en usernaam in cookies...)

Dit script staat onder de categorie 'Beginner'! En in die zin vind 'k hem zeker voldoende!
TJVB tvb
TJVB tvb
20 jaar geleden
 
0 +1 -0 -1
@Lode ik ben het niet helemaal met je eens.
Ik heb ook wel eens een stuk slechter gezien, maar dat betekent niet dat je nu tevreden moet zijn.

De zwakte zit namelijk wel in de hash. Als ik er nu achter kom wat de opbouw van de hash is hoef ik alleen maar iemands user_id te hebben.
Dan nog een programma om de headers te wijzigen. Dan hoef ik alleen maar voor alle browser varianten te checken of ik ingelogd kom.

Voor een beginners script is het opzich wel goed, maar door elkaar te wijzen op de zwaktes kunnen we het steeds weer verbeteren.
Lode
Lode
20 jaar geleden
 
0 +1 -0 -1
Tuurlijk kan ook veel beter en veiliger nog.
over hashes e.d. heb ik al zoveel discussies gehad o.a:
http://www.phphulp.nl/forum/showtopic.php?cat=6&id=44765

Maar goed voor TS dat je het even aanhaalt wellicht inderdaad!
Leef je uit ik kan nog wel wat dingen verzinnen... Maar werk roept...
Frank -
Frank -
20 jaar geleden
 
0 +1 -0 -1
Ziet er aardig uit, al zou ik zelf het cookie met de hash vervangen door een sessie. Het controleren op een geldige hash zou ik in SQL doen, die kan prima vergelijkingen maken. Het is iets sneller.
Lode
Lode
20 jaar geleden
 
0 +1 -0 -1
standaard (gare) php sessions heb ik persoonlijk al een hele tijd geleden het bos in gestuurd!

sessions gebruiken ook gewoon cookies maar dat weet jij ook wel :-]
tenzij je session.use_trans_sid gebruikt maar dat wil je al helemaal niet.
Frank -
Frank -
20 jaar geleden
 
0 +1 -0 -1
@Lode: Sessions beheren met de database, dat werkt uitstekend: snel, veilig en schaalbaar (denk aan loadbalancers die meerdere webservers en databases aansturen). Dat er aan de clientkant gewoon een soort van cookie staat, dat blijf je houden, dat is een gevolg van het gebruik van http. Dat is stateless, dus moet je wel een koekje gebruiken.
Bo az
Bo az
20 jaar geleden
 
0 +1 -0 -1
Wat me opvalt is dat je wel pdo gebruikt maar geen prepared statements. Ik denk toch dat, dat een stuk veiliger zou zijn, nu moet ik maar zien hoe ik een ge escapede waarde in de login methode krijg?

Ook valt me op dat je het id van de gebruiker ophaalt adhv de combinatie username/password, in die query zit zelfs een limit. Dat wijst al op een foutje, je hoort namelijk maar maximaal 1 resultaat terug te kunnen krijgen (2 gebruikers met de zelfde username/password is toch een beetje raar). Daarom zou je eigenlijk een UNIQUE constraint aan je create table scriptje moeten toevoegen, kan meteen die limit uit die query.
TJVB tvb
TJVB tvb
20 jaar geleden
 
0 +1 -0 -1
Boaz, Dat van die limit is wel goed. Doordat je die limit meegeeft stopt die nadat er 1 gevonden is. Dit scheelt gemiddeld het doorzoeken van een halve tabel.
Dit gaat dus om kleine performence verbeteringen.

Lode, een cookie puur voor de sessie of voor alles vindt ik nogal een verschil. Als een sessie niet helemaal zuiver id schiet ik hem af, bij cookies is dat wat lastiger aangezien die client side gezet kunnen worden.
Jurgen assaasas
Jurgen assaasas
20 jaar geleden
 
0 +1 -0 -1
@TJVB op het moment dat jij gewoon een uniqe constraint geeft is het niet mogelijk om meerdere rijen te krijgen in je resultaat. Dit is misschien weer een extra controle. Stel je hebt 2 users met dezelfde username en pass, maar met verschillende rechten dan krijgt een bezoeker misschien wel modrechten(bij wijze van). Een uniqe op username en deze mogelijkheid is ook verleden tijd.
Mark Pieper
Mark Pieper
20 jaar geleden
 
0 +1 -0 -1
In ieder geval iedereen bedankt voor de opmerkingen. Ik gebruik in dit geval geen sessies, omdat als de gebruiker ingelogd wil blijven, moet je ze allebei gebruiken. Daarom gebruik ik alleen cookies.
Ook over de salt heb ik nagedacht, maar inderdaad dit script staat in de beginnersafdeling. En als je er dan een salt bij plakt, neemt iedereen die klakkeloos over. Ook word het maken van een registratie script dan moeilijker voor velen.
Voor die opmerking over LIMIT, ik zal de sql-dump aanpassen, en bij username UNIQUE zetten.
Edit:
Over die prepared statements, de waarden worden gecontroleerd met ctype_alphanum, en over het wachtwoord gaat sha1(). Lijkt me niet nodig dus. Ook over de browser gaat een hash, dus daar hoeft ook niet naar gekeken te worden.
Bo az
Bo az
20 jaar geleden
 
0 +1 -0 -1
Quote:
Over die prepared statements, de waarden worden gecontroleerd met ctype_alphanum, en over het wachtwoord gaat sha1(). Lijkt me niet nodig dus. Ook over de browser gaat een hash, dus daar hoeft ook niet naar gekeken te worden.


Is ook een mogelijkheid, maar als ik jou was zou ik toch nog maar eens goed naar de login methode kijken, daar gaat $name zo de query in.

Edit:
Ik zie nu dat je die controleert voor je de methode aan roept. Het kan, maar het zou mijn persoonlijke voorkeur niet hebben omdat het nogal fout gevoelig is.
Frank -
Frank -
20 jaar geleden
 
0 +1 -0 -1
Het mixen van gewone queries met userinput en prepared statements is altijd een slecht plan. Nu loop je het risico dat je fouten gaat maken. Queries die variabelen vereisen, doe je altijd met prepared statements, dan kan er onmogelijk wat fout gaan. En om nog een stapje verder te gaan, doe gewoon alles via prepared statements, dan kun je eenvoudig variabelen toevoegen wanneer je dat nodig hebt. Dat zorgt voor eenvoudige en veilige php-code.
Mark Pieper
Mark Pieper
20 jaar geleden
 
0 +1 -0 -1
De validatie van de gebruikersnaam vindt niet plaats in de class zelf, omdat de 1 [a-Z] toestaat, de ander wil er nog getallen bij, weer 1 spaties, de ander streepjes.

@pgFrank, ik gebruik bijna nooit prepared statements, ik valideer meestal gewoon.
Frank -
Frank -
20 jaar geleden
 
0 +1 -0 -1
Jij kunt vrijwel nooit zo goed valideren als dat een prepared statement de boel kan beveiligen. Daarmee voorkom je ook SQL-injection en vastlopers op quotes '. Ik gebruik uitsluitend prepared statements, zelfs al zijn er geen parameters. Dat geeft mij maximale flexibiliteit en veiligheid. Wat wil je nog meer?
Mark Pieper
Mark Pieper
20 jaar geleden
 
0 +1 -0 -1
Oke, ik zal het erinbouwen, als ik een volgende versie maak. Ik zal dan ook een betere fingerprint erinbouwen, ik heb net namelijk dat topic gelezen, een salt, en alleen een unieke hash in de cookie zetten.
Han eev
Han eev
20 jaar geleden
 
0 +1 -0 -1
Ik heb nog nooit in scripts(hier op phphulp) Prepared statements gezien en gehoord. Hoe gaat dat precies in zijn werk? Als ik het zo zie en lees op mysql.com is het erg omslachtig. Misschien doe ik iets verkeert?
Uitleg? Heb je misschien goeie tut, ik wil graag meer leren over goed gebruik van databases. en jij hebt altijd van dat leuke commentaar :) (en daar leer ik ook veel van)
Mark Pieper
Mark Pieper
20 jaar geleden
 
0 +1 -0 -1
Kijk eens op php.net/pdo, bijvoorbeeld: http://nl.php.net/manual/nl/function.PDO-prepare.php
Frank -
Frank -
20 jaar geleden
 
0 +1 -0 -1
@Han: Zie dit script, daar staan ze toch echt in! De mysqli_ en pg_ -functies van PHP kennen ook prepared stataments, zie mysqli_stmt_prepare() en pg_query_params().

PHP kent dit voor vele databases, alleen de mysql-functies kennen geen prepared statements. Dat is met mysqli dus opgelost.
Lode
Lode
20 jaar geleden
 
0 +1 -0 -1
Je kan binnen mysql wel prepared statements gebruiken middels queries.

http://dev.mysql.com/doc/refman/5.0/en/transactional-statements.html
Gebruiker PHP
Gebruiker PHP
20 jaar geleden
 
0 +1 -0 -1
Best netjes alleen heb ik toch wat aanmerkingen.

Allereerst de hash, sha1. Ik zou dat aanpasbaar maken, dus dat je een constante maakt die het algoritme bevat welke gebruikt zal moeten worden, dit kun je doen met behulp van de functie hash in PHP.

Daarnaast zou je ook een salt kunnen gebruiken om het bruteforcen van een wachtwoord nog moeilijker te maken.

Wat je ook nog zou kunnen doen is cookies locken aan IP, host en user-agent.

Ook zou ik de hash gewoon 100% random maken, dus geen gegevens van de bezoeker e.d. in die hash plaatsen.

Wat ik vreemd vind is dat je zelf een PDOException throws nadat je zelf hebt gekeken of een query is gelukt maar als een query faalt gooit PDO zelf toch een PDOExepction?

Misschien eens naar prepared statements kijken?

Het IP zou je misschien ook voor de zekerheid kunen escapen.

In je SQL geef je het veld ip een lengte van 15, beter is 39, zo houd je ook rekening met mensen die een IPV6 IP hebben.

In je voorbeeld geef je geen errormode mee aan PHP, is het niet beter om daar gelijk de Exepction error mode aan te zetten?
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Mark Pieper
Mark Pieper
20 jaar geleden
 
0 +1 -0 -1
Bedankt voor de input, ik probeer dit te verwerken!

Om te reageren heb je een account nodig en je moet ingelogd zijn.

Inhoudsopgave

  1. simple-auth-class

Labels

  • Geen tags toegevoegd.

Navigatie

 
 

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.