Tutorial: Kako napraviti skriptu za registraciju i login

Tutorial: Kako napraviti skriptu za registraciju i login

offline
  • Nemanja
  • Web Designer and Developer
  • Pridružio: 24 Jan 2007
  • Poruke: 266

Ukoliko sami programirate neki CMS sajt ovo je najbitniji deo koji morate dobro programirati. Takođe, ovaj deo je prvi na udaru kada su XSS napadi u pitanju.

Na samom početku trebamo napraviti bazu. Na skoro svakom serveru (virtuelnom ili fizickom) postoji program koji koji se zove phpmyadmin. Pomoću njega lako možemo napraviti potrebnu bazu, tabele i polja.
Za ovaj tutorijal biće vam potrebna baza ime_baze u kojoj ćemo napraviti tabelu Korisnici.
Tabela korisnici će od polja imati: Ime, Prezime, KorisničkoIme i Lozinka.
Takođe, možemo napisati kod koji će sve ovo izvršiti umesto nas.
CREATE TABLE `Korisnici` (   `Ime` varchar(32),   `Prezime` varchar(32),   `KorisnickoIme` varchar(32),   `Lozinka` varchar(32) )

Pre svega treba napraviti jedan php fajl u kome ćemo uneti podatke za pristup bazi. Ovo je bitno jer kasnije kada trebate ponovo uspostaviti vezu sa bazom dovoljnoje samo uključiti ovaj fajl. Takođe, kada menjamo neke podatke dovoljno ih je promeniti samo na ovoj strani. Ovu stranu zvaćemo:
config.php.
<?php define('DB_HOST', 'localhost'); //Za pristup bazi koja se nalazi na istom hostingu define('DB_USER', 'ime_korisnika'); define('DB_PASSWORD', 'lozinka_baze'); define('DB_DATABASE', 'ime_baze'); ?>

E sada kada imamo ovaj konfiguracioni fajl lako ćemo ga posle toga implementirati gde bude potrebno. Sada moramo napraviti formular za registraciju. Ovu stranu zvaćemo:
register.php
<body>    <form name="registracionaForma" action="izvrsi-registraciju.php" method="post">       Ime:<input type="text" name="ime" />       Prezime:<input type="text" name="prezime" />       Korisničko ime:<input type="text" name="korisnickoIme" />       Lozinka:<input type="password" name="lozinka" />       <input type="submit" value="U redu" />    </form> </body>
E sada da objasnimo malo ovaj kod. Na samom početku u tagu form dodali smo deo action="izvrsi-registraciju". To znači da prilikom pritiska na dugme U redu forma poziva skriptu izvrsi-registraciju.php.
Nakon toga imamo method="post" . To znači da se sva transakcija izmedju strana vrši post metodom. Pored post metode, postoji i get metoda. Mi ćemo koristiti post metodu jer je ona sigurnija. Kod get metode svi podaci koji se prebacuju izmedju strana su vidljivi u samoj putanji fajla.
Ostalo bi trebalo da bude koliko toliko jasno.

E sada da bismo ove podatke uneli u bazu i samog korisnika registrovali moramo da napravimo stranu:
izvrsi-registraciju.php
<?php    //Dodaćemo fajl koji smo malopre kreirali kako bi smo uspostavili vezu sa bazom    include('config.php');           //Sada ćemo ostvariti konekciju sa mysql serverom. DB_HOST, DB_USER, DB_PASSWORD su podaci koje smo definisali u fajlu config.php    $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);    //Ukoliko strana ne uspe da uspostavi vezu sa serverom prikazuje poruku o grešci    if(!$link) {die('Greska prilikom uspostave veze sa serverom. Molimo obratite se administratorskoj podrsci! Greska: ' . mysql_error());}        //Kada se konektujemo na mysql server potrebno je uspostaviti vezu sa bazom. DB_DATABASE smo definisali u fajlu config.php    $db = mysql_select_db(DB_DATABASE);    //Ukoliko strana ne uspe da uspostavi vezu sa bazom prikazuje poruku o grešci    if(!$db) {die("Problem sa definisanjem baze. Molimo obratite se administratorskoj podrsci" . mysql_error());}        //Jedna od najbitnijih funkcija. Ova funkcija sprečava takozvani SQL Injection. Laički rečeno ovim sprečavamo da nam neko preotme upravljanje bazom.    function clean($str) {       $str = @trim($str);       if(get_magic_quotes_gpc()) {          $str = stripslashes($str);       }       return mysql_real_escape_string($str);    }        //Prikupljamo podatke sa strane register.php, funkcijom clean proveravamo i otklanjamo SQL injection i definišemo ih u promenljivim.    $ime = clean($_POST['ime']);    $prezime = clean($_POST['prezime']);    $korisnickoIme = clean($_POST['korisnickoIme']);    $password = clean($_POST['lozinka']);        //U bazi nesmemo imati dva ista korisnička imena. Ovom petljom proveravamo da li u bazi već postoji korisnik sa tim korisničkim imenom    if($username != '') {       $qry = "SELECT * FROM Korisnici WHERE Username='$username'";       $result = mysql_query($qry);       if($result) {          if(mysql_num_rows($result) > 0) {             //Ukoliko u bazi postoji korisnik sa istim korisničkim imenom strana nas preusmerava na stranu error.php             header ("location: error.php");             exit();          }          @mysql_free_result($result);       }       else {          die("Problem sa proverom duplih username-a" . mysql_error()); //Ukoliko dodje do nekog problema sa proverom prikazuje poruku o grešci       }    }        //Ukoliko podaci prodju sve gore navedene provere potrebno ih je i uneti u bazu    $qry = "INSERT INTO Korisnici(Korisnici_Ime, Korisnici_Prezime, Korisnici_Username, Korisnici_Password) VALUES('$ime','$prezime','$username','".md5($_POST['lozinka'])."')";    $result = @mysql_query($qry);        //'".md5($_POST['lozinka'])."' - Ukoliko dodje do preotimanja baze i neko pokupi podatke iz baze, pomoću metode md5 kriptovanja lozinka će mu biti potpuno nečitljiva (primer: d131dd02c5e6eec4).        //Proveravamo da li su podaci uspešno uneti u bazu    if($result) {       header("location: ../login.php"); //Ukoliko jesu, preusmeravamo se na stranu login.php       exit();    }else {       //Ukoliko je došlo do greške prikazujemo poruku o grešci       die("Greška prilikom izvršavanja upita: " . mysql_error());    } ?>

Sada kada smo napravili stranu za regisrtraciju trebamo napraviti stranu za pristupanje.
Prvo moramo napraviti formu. Ovu stranu nazvaćemo:
login.php
<body>    <form name="pristupnaForma" action="izvrsi-login.php" method="post">       Korisničko ime:<input type="text" name="korisnickoIme" />       Lozinka:<input type="password" name="lozinka" />       <input type="submit" value="U redu" />    </form> </body>

Ovu formu smo objasnili malo gore. Sada je potrebno napraviti stranu:
izvrsi-login.php
<?php    //Otvaramo novu sesiju kako bi smo kasnije mogli da stavimo podatke u nju    session_start();        //Prvih nekoliko elemenata smo objasnili na ranijem slajdu    include('config.php');           $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);    if(!$link) {die('Greska prilikom uspostave veze sa serverom. Molimo obratite se administratorskoj podrsci! Greska: ' . mysql_error());}        $db = mysql_select_db(DB_DATABASE);    if(!$db) {die("Problem sa definisanjem baze. Molimo obratite se administratorskoj podrsci" . mysql_error());}        function clean($str) {       $str = @trim($str);       if(get_magic_quotes_gpc()) {          $str = stripslashes($str);       }       return mysql_real_escape_string($str);    }        $login = clean($_POST['korisnickoIme']);    $password = clean($_POST['lozinka']);        //Sada je potrebno da podatke o korisniku povučemo iz baze    //Uporedjujemo dve lozinke dobijene enkripcijom md5. Podatak enkriptovan md5 hash tagom teško je dekriptovati    $qry="SELECT Ime, Prezime, KorisnickoIme, Lozinka WHERE KorisnickoIme='$login' AND Lozinka='".md5($_POST['lozinka'])."'";    $result=mysql_query($qry);        //Proveravamo da li u bazi postoji korisnik sa ovim pristupnim podacima    if($result) {       if(mysql_num_rows($result) == 1) {          //Ukoliko postoji          session_regenerate_id();          $member = mysql_fetch_assoc($result);          //U sesiji stavljamo podatke koje ćemo kasnije upotrebljavati na stranama          $_SESSION['SESS_KORISNICI_IME'] = $member['Ime'];          $_SESSION['SESS_KORISNICI_PREZIME'] = $member['Prezime'];          $_SESSION['SESS_KORISNICI_USERNAME'] = $member['Username'];                    //Preusmeravamo se na početnu stranu nakon pristupa          header("location: ../home.php");          exit();       } else {                 //Ukoliko se u bazi ne nalazi korisnik sa tim pristupnim podacima, ili ukoliko su pristupni podaci netačni, prikazujemo stranu o grešci          header("location: ../error.php");          exit();       }    } else {       die("Greska prilikom izvrsavanja upita!". mysql_error());    } ?>

E sada, da bi smo sprečili lako zaobilaženje login strane (www.primer.php/home.php), na svakoj strani za koju je potrebno prijavljivanje u samom vrhu dodaćemo kod:
<?php include("auth.php"); ?>

Sada ćemo napraviti stranu:
auth.php
<?php    //Startujemo sesiju    session_start();        //Proveravamo da li je otvorena sesija na ovoj strani i da li u poljima ima podataka    if(!isset($_SESSION['SESS_KORISNICI_IME']) || (trim($_SESSION['SESS_KORISNICI_IME']) == '')) {        //Ukoliko nije, preusmeravamo na stranu o grešci       header("location: ../login/access-denied.php");       exit();    } ?>

Uživajte Smile



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Srđan Tot
  • Am I evil? I am man, yes I am.
  • Pridružio: 12 Jul 2005
  • Poruke: 2483
  • Gde živiš: Ljubljana

Na brzinu sam preleteo preko teksta i, koliko vidim, nikgde nema objašnjenje kako baza treba da izgleda.
Verujem da korisnicima koji će koristiti ovaj tutorijal, neće moći sami da se snađu i naprave bazu + potrebne tabele.



offline
  • Nemanja
  • Web Designer and Developer
  • Pridružio: 24 Jan 2007
  • Poruke: 266

Srki_82 ::Na brzinu sam preleteo preko teksta i, koliko vidim, nikgde nema objašnjenje kako baza treba da izgleda.
Verujem da korisnicima koji će koristiti ovaj tutorijal, neće moći sami da se snađu i naprave bazu + potrebne tabele.


Sređeno Wink

offline
  • PHP Developer
  • Pridružio: 02 Okt 2005
  • Poruke: 546

Lep primer ja imam par napomena ako neko zeli ovo primeniti u praksi.
Trebalo bi koristiti mysqli konetkor umesto musql.
Dodati jedinstveni ndex na Korisnicko ime da se ubrza pretraga i osigura da nemoze da postoje dva indenticna.
ALTER TABLE `Korisnici` ADD UNIQUE (`KorisnickoIme`);

md5 bez salta se smatra jako slabom zastitom.
Predlog je koristiti sha1 ili nasto jos jace, i obavezno posoliti.
recimo u config dodati
define ('HASH_SALT','d5=.<A~k3i');
i onda koristiti hash('sha1',$password.HASH_SALT);
ili cak hash('sha1',$korisnickoIme.$password.HASH_SALT); u ovom drugom slucaju treba paziti da prilikom promene korisnickog imena treba trazti password i ponovi izgenerisati hash.
Stim da sha1 zauzuma 40 karaktera pa treba u bazi odvoiti dovoljno mesta
`Lozinka` varchar(40)
detaljnije imate ovde
http://www.php.net/manual/en/function.hash.php

Za detaljnije informacije o pravilnoj zastiti sifri u bazi imate ovde tekst na negleskom
https://(zabranjeno)station.net/hashing-security.htm
Smile zabranjeno evo posredni preko gogle
goo.gl/25RfcF

offline
  • C# and PHP Developer
  • Pridružio: 16 Feb 2011
  • Poruke: 1622
  • Gde živiš: Pancevo

@HUNT3R
Cenim tvoj trud i ulozeno vreme u pisanju ovoga, ako zelis da ova tema bude izdvojeni clanak moraces da menjas neke stvari...

Zamerke:

Koristis mysql koji je deprecated u poslednjoj verziji:
http://php.net/manual/de/migration55.deprecated.php
Promeni sve to u PDO ili MySQLi

Opet kazem rutina je bitna i godine iskustva. U svakom drugom fajlu otvaras konekciju sa bazom sto nije dobra praksa. To ti je kao fizikalija kad govoris fizikalcu e daj mi cekic, on taman sedne ti mu kazes e dodaj mi klesta. Tako i ti cimas server sada. Baza se na jednom mestu definise konekcija i ona dobije svoj ID i pomocu njega je dostupna svuda u fajlove.
Iz tog razloga ovde kod tebe je neophodan Front Controller preko kojeg ce ici svi http zahtevi.

Da si sve to uradio u MySQLi imao bi mnogo vise mogucnosti i sigurnosti jer mysqli ti pruza bindovanje i prepared statements koji rade amazonski posao.

Kao sto si prikljucivao config tako si mogao i klasu za bazu da ubacis u fajlove a ne stalno da otvaras nove konekcije.

Zamisli sada da zelis da promenis bazu? Morao bi 15 fajlova da menjas da bi se konektovao na bazu a ovako bi menjao samo na jednom.

Tabele i kolone u bazi praktikuj da pises malim slovima a ne velikim

Ko je trenutno na forumu
 

Ukupno su 592 korisnika na forumu :: 68 registrovanih, 4 sakrivenih i 520 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 1567 - dana 15 Jul 2016 19:18

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: 357magnum, _Sale, A.R.Chafee.Jr., aleksmajstor, awathorn, Belac91, beowl, Botovac, Bov80, bozidar79, CheefCoach, Cvijo_ue, cvrle312, d.arsenal321, darkangel, dragon986, dzenan_y, galijot, hooraay, ikan, ilic.markoilic.marko, Insan, jery2, Kubovac, Libertas, lord sir giga, madza, Marko Marković2, Maschinekalibar, matorigile, MB120mm, mercedesamgzakon, Mihajlo2, MikeHammer, miroslavtm12, Misirac, Mixelotti, Mlav, N.e.m.a.nj.a., Nenad Stankovic, nenad81, Perko91, powSrb, Predrag Macura, radionica1, Rakenica, repac2, ruger357, sasa.zoric, scimitar19, shaja1, Sirius, Srki94, SsssssNOVI, stefanmpurtic, trajkoni018, USSVoyager, vathra, VJ, voja64, vojnik švejk, W123, Warhawk, weez, White Knight, wilson_16547, Zerajic, zlatkovuka