Gå til innhold

GUIDE: Brukersystem i PHP med database og sikkerhet!


Anbefalte innlegg

- PHP – BRUKERSYSTEM – GUIDE – EIVIND218 ! –

 

For å gjøre dette anbefalles det å ha en webserver eller localhost ( www.wamp.com ).

 

Da starer jeg med MySQL databasen..

Vi kaller Tabellen ”users” da det er ganske logisk når du skal ha brukere..

 

 

 

CREATE TABLE `users` (

`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,

`brukernavn` VARCHAR( 255 ) NOT NULL ,

`passord` VARCHAR( 255 ) NOT NULL ,

`email` VARCHAR( 255 ) NOT NULL ,

`ip` VARCHAR( 255 ) NOT NULL ,

`regdato` DATE NOT NULL ,

`status` VARCHAR( 255 ) NOT NULL DEFAULT '0',

`moderator` VARCHAR( 255 ) NOT NULL DEFAULT '0'

`status` VARCHAR( 255 ) NOT NULL DEFAULT '0'

) ENGINE = innodb;

 

 

 

Id identifiserer brukeren, Med et tall...

Brukernavn er brukernavnet til brukeren,

Passord er det passordet man skal logge inn med.

Emailen er emailen til brukeren

IP’en til brukeren er noe som identifiserer dataen han ble registrert hos.

Regdato er datoen brukerene ble registrert.

Moderator er et tall, 1-X. Ettersom hvilken status brukeren skal ha.. ( admin f.eks )

Status er om brukeren er f.eks deaktivert eller utestengt fra systemet.

 

Her har vi config.php:

 

 

 

<?php

 

$host = "localhost"; // Normalt localhost

$brukernavn = "brukernavn"; // brukernavn til MySQL

$passord = "Passord"; // Passord til MySQL

$database = "Database"; // Databasen du har tabellene i

 

$q = mysql_connect("$host", "$brukernavn", "$passord"); // Kobler til databasen

$q = mysql_select_db("$database"); // Velger databasen

 

$l = mysql_query("SELECT * FROM users WHERE id='$_SESSION[id]'");

// Skjekker om brukeren er logget inn

 

$l = mysql_fetch_array($l); // Henter ut informasjonen om brukeren

 

 

/* Inkluderer funksjoner */

 

// Her kan du inkludere funksjoner som quote_smart, Bbkoder osv..

// Spør meg, Kanskje du får en..

 

?>

 

 

 

Anbefaller å ikke kopiere, Men lese komentarene på alle filer!

 

Registrer.php:

 

 

<?php

ob_start();

session_start();

 

include("config.php");

 

if (isset($_POST[submit])) {

 

 

$brukernavn = $_POST[brukernavn];

$passord = $_POST[passord];

$passord2 = $_POST[passord2];

$email = $_POST;

 

if(empty($brukernavn)) {

echo ("Du har glemt å fylle ut brukernavn!<br>");

}

if(empty($passord)) {

echo("Du glemte å fylle ut passordet!<br>");

}

if(empty($passord2)) {

echo("Du glemte å gjenta passordet!<br>");

}

if($passord != $passord2) {

echo ("Du har ikke skrevet inn samme passord i begge passordfeltene!<br>");

}

else

{

$passord2 = md5($passord);

 

$skjekknavn = mysql_query("SELECT brukernavn FROM users WHERE brukernavn='$brukernavn'");

$skjekknavn = mysql_num_rows($skjekknavn);

 

$skjekkemail = mysql_query("SELECT email FROM users WHERE email='$email'");

$skjekkmail2 = mysql_num_rows($skjekkemail);

 

if($skjekkmail2>0|$skjekknavn>0) {

echo ("Finn deg et annet brukernavn eller en annen email!");

}

else

{

$brukernavn = htmlspecialchars($brukernavn);

$passord = $passord2;

$email = $email;

$ip = $_SERVER[`REMOTE_ADDR`];

$regdato = date("j, n, Y");

$query = mysql_query("INSERT INTO users (`brukernavn`, `passord`, `email`, `ip`, `regdato`, ) VALUES ('$brukernavn', '$passord', '$email', '$ip', '$regdato')");

 

echo("Du er registrert og kan starte å spillet på <a href=\"index.php\">forsiden</a>");

 

}

}

}

else

{

?>

<form method="POST" action="">

<br>

<br>

<table width="405" height="168" align="center">

<tr align="left" valign="top">

<td width="139"><img src="img/loginpic.gif" width="138" height="159"></td>

<td width="254"><div align="center"><br>

Ønsket brukernavn:<br>

<input type="text" name="brukernavn" />

<br />

Passord:<br>

<input type="password" name="passord">

<br />

Gjenta passord:<br />

<input type="password" name="passord2" />

<br />

Email:<br />

<input type="text" name="email" />

<br />

<input type="submit" name="submit" value="Registrer!">

<br />

<a href="index.php">Logg inn!</a></div></td>

</tr>

</table>

</form>

<?php

}

?>

 

 

 

Så må jo brukerene logge inn et sted;

( login.php )

 

 

 

Her er altså et kjapt brukersystem guide 

 

For å bare tillate brukere på et område legger du denne koden på siden:

 

 

 

Endret av Eivind218
Lenke til kommentar
Videoannonse
Annonse

Veldig bra guide men jeg mener jeg har lest at alt innhold som legges ut på forumet er "eiendom" til diskusjon.no og kan dermed ikke settes kopirettigheter på fra andre en de ;)

 

Kjempe bra at noen gidder lage en så bra guide, vet det er mye spørsmål om dette :)

Lenke til kommentar

:nei: Beklager at jeg er negativ, men hvor i alle dager skal jeg begynne? I mine øyne er det langt fra holdbart (det er dog en start ;)).

  1. Databasen

    1. "Id identifiserer brukeren, Med et tall..."
      Hvorfor int 11? Int er 32 bit og blir aldri lengre enn 10 siffer ...
    2. "Passord er det passordet man skal logge inn med."
      Hvorfor 255 tegn lang når du bruker md5? Her burde det vært fast antall tegn på 32.
    3. "IP’en til brukeren er noe som identifiserer dataen han ble registrert hos."
      Når ble IPer opp mot 255 tegn lange? Her bør man strengt tatt bruke int da en IPv4-adresse passer rett inn hvis int-en er unsigned
    4. "Moderator er et tall, 1-X. Ettersom hvilken status brukeren skal ha.. ( admin f.eks )"
      Du sier tall, så hvorfor er da feltet varchar?
    5. "Status er om brukeren er f.eks deaktivert eller utestengt fra systemet."
      Status bør ideelt sett enten være en int eller en enum. Char/varchar er ingen god løsning, spesielt ikke i en guide, «tutorial» e.l.

[*]Koden genereren endel notice pga. ting ala $_POST[submit] (skal i mine øyne enten være $_POST['submit'] eller $_POST["submit"])

[*]SQL-injection kan utføres i blant annet "$skjekkemail = mysql_query("SELECT email FROM users WHERE email='$email'");". Valider input før du bruker de. Et meget godt tips er å aldri flytte data over fra $_POST, $_GET osv. før de er validert.

[*]Utdrag fra registrer.php

if($skjekkmail2>0|$skjekknavn>0) {
echo ("Finn deg et annet brukernavn eller en annen email!");
}

Hvorfor bruker du en bit-operator her? Burde det ikke vært en logisk operator? Dvs. || eller ev. OR. Videre skjønner jeg fint lite av hvorfor du sier at enten brukernavnet eller email-adressen er opptatt. Er det ikke *litt* mer brukervennlig å si eksakt hva som er opptatt? :shrug:

[*]Koden er i mine øyne ikke mye gjenbrukbar når den inneholder html. Hvorfor er ikke «business logic» plassert i noen funksjoner og brukt et sted hvor du har presentasjonslogikk («presentation logic»)?

Endret av Ernie
Lenke til kommentar

Indentering er et fint ord.

 

or die(mysql_error());

MySQL-feil skal aldri skrives ut til www.

 

ob_start()

Skal strengt tatt ikke være nødvendig om du har gjort et skikkelig arbeid.

 

md5 kan knekkes.

Anbefaler bruk av sha1() i tillegg til en ekstra string som er lagret i databasen for hver bruker. eks:

sha1("fka0fuj83ajf3ahf328hafd387h38" . $pass);

 

align-attributen bør ikke brukes.

 

Table er unødvendig å bruke i en så liten form.

Etter min mening er labels og p bedre å bruke her.

 

Du bør også bruke bedre navn på variabler. Dette er et dårlig eksempel som du har brukt:

$l = mysql_fetch_array($l); // Henter ut informasjonen om brukeren

Endret av BigJackW
Lenke til kommentar
md5 kan lett dekrypteres.

Anbefaler bruk av sha1() i tillegg til en ekstra string som er lagret i databasen for hver bruker. eks:

sha1("fka0fuj83ajf3ahf328hafd387h38" . $pass);

Javel, da forventer jeg at du kan knekke denne:

fe014471eb51e23bb94688c885ee9bca

8 tegn med bare a-z. Det du vil oppdage er at md5 ikke kan dekrypteres, men knekkes enten v.hj.a bruteforce eller rainbow table. Slikt tar tid. Så lenge man tilsetter salt i passordet eller passordet er tilstrekkelig langt nok er det få som kommer til å bruke tid på å knekke passordene.

Endret av Ernie
Lenke til kommentar

Nå mente jeg ikke dekrypteres da, men som du sier; bruteforce / rainbow-table.

 

Står btw

"alskdjfh" i hashen din.

 

sha1 bør uansett brukes fremfor md5, da md5 har noen svakheter som igjen fører til uegnet bruk innenfor sikkerhet (Les: her. Står også noe om det på wikipedia).

Endret av BigJackW
Lenke til kommentar

Flott at folk deler kode/guider med andre, men det bør være nogenlunde feilfritt.

Det er alt for mange "copy-paste"-programmerere både her og på andre forum som kopierer kode ukritisk uten å egentlig skjønne hva koden gjør...

For en nybegynner kan guiden virke bra som en av kommentarene i tråden her sier.

Den kan ikke kalles bra når den inneholder såpass mye feil og i tillegg inneholder såpass store sikkerhetshull.

 

Noen kommentarer til koden i tillegg til det Ernie og BigJackW har påpekt:

 

...

if(isset($_POST['login'])) {

$brukernavn1 = $_POST[brukernavn]
$brukernavn = htmlspecialchars($brukernavn1);
$passord = md5($_POST[passord]);

$info = mysql_query("SELECT * FROM users WHERE brukernavn='$brukernavn'") or die(mysql_error());
$info = mysql_fetch_array($info);

if($info[passord] != $passord) {
echo ("Feil brukernavn/Passord");
} else {

$query = mysql_query("SELECT * FROM users WHERE brukernavn='$brukernavn'") or die(mysql_error());
$query = mysql_fetch_array($query);

$_SESSION[id] = $query[id];
echo("<meta http-equiv=\"Refresh\" content=\"0; URL=index.php\">");
echo("Logger inn! Vennligst vent!");

}
}

...

 

Hvorfor henter du ut samme data to ganger fra databasen? begge spørringene henter samme data.

$info inneholder allerede samme data som du vil hente ut med $query...

 

Du sjekker heller ikke om databasen returnerer noe data før du prøver å benytte det.

mysql_fetch_array returnerer false dersom ingen rader er funnet. Enkelt eksempel på hvordan det kan sjekkes:

 

$brukernavn = mysql_real_escape_string($brukernavn);

$sql = "SELECT * FROM users WHERE brukernavn='$brukernavn'";
$resultat = mysql_query($sql)
if($resultat) {
if($rad = mysql_fetch_array($resultat)) {
	$_SESSION['id'] = $rad['id'];		
}
else {
	//Ingen rader funnet. Håndtere feilen
}
}
else {
//Spørringen feilet. Håndtere feilen
}

 

 

En god regel er å sjekke at $_POST / $_GET er satt og inneholder verdi før de benyttes. Du sjekker at login er satt, men ikke brukernavn og passord..

I de fleste tilfeller så vil de være satt hvis login er satt, men man bør være obs på at det er en smal sak å konstruere egne POST forespørsler.$_POST['brukernavn'] og $_POST['passord'] kan også være tomme.

Eksempel på sjekk av POST-verdi:

 

if(isset($_POST['verdi']) && !empty($_POST['verdi'])) {
$verdi = trim($_POST['verdi']);	
}
else {
//Verdi ikke satt eller tom	
}

 

Dersom 0 er gyldig input må man gjøre det litt annerledes da empty($variabel) returnerer true altså tomt hvis $variabel inneholder 0.

 

if(isset($_POST['verdi'][0])) {
$verdi = trim($_POST['verdi']);		
}
else {
//Verdi ikke satt	
}

 

 

Det er mange ting å pirke på i denne guiden, men jeg lar det være med dette.

Endret av Zandar
Lenke til kommentar

en annen ting... du trenger ikke spørre databasen for hver gang en innlogget bruker skal se en side. det holder lenge med å sette en session-variabel når brukeren logger inn og sjekke den hver request.

 

edit: svar til post: feilsøkings projekt med andre ord? ;)

Endret av grimjoey
Lenke til kommentar
Takk for tips, Men har da aldri sagt at den er helt perfekt? :p

 

Så dt er ikke et brukersystem man skal kopiere helt av..

Så derfor er det sånn.. Så man faktisk må jobbe litt selv ;)

 

 

GUIDE: Brukersystem i PHP med database og sikkerhet!

:p

Endret av BigJackW
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...