Neustrašiva autentifikacija php. HTTP Instaliranje zaštite na stranicu koristeći MySQL i PHP. Primjer #7 Primjer sažete HTTP provjere autentičnosti
Naučit ćemo kako napraviti jednostavnu autentifikaciju korisnika na stranici. Stranica može imati stranice samo za ovlaštene korisnike, a one će u potpunosti funkcionirati ako im dodamo našu blokadu provjere autentičnosti. Za izradu vam je potrebna MySQL baza podataka. Može imati 5 stupaca (minimalno) ili više ako želite dodati podatke o korisnicima. Nazovimo bazu podataka “Userauth”.
Kreirajmo u njemu sljedeća polja: ID za brojanje broja korisnika, UID za jedinstveni identifikacijski broj korisnika, Korisničko ime za ime korisnika, Email za njegovu e-mail adresu i Lozinka za lozinku. Svoju postojeću bazu podataka možete koristiti za autorizaciju korisnika, samo, kao i u slučaju nove baze podataka, u njoj napravite sljedeću tablicu.
MySQL kod
CREATE TABLE `korisnici` (`ID` int (11) NOT NULL AUTO_INCREMENT, `UID` int (11) NOT NULL, `Korisničko ime` tekst NIJE NULL, `Email` tekst NIJE NULL, `Password` tekst NIJE NULL, PRIMARNI KLJUČ (`ID`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Kreirajmo sada datoteku "sql.php". Odgovoran je za povezivanje s bazom podataka. Ovaj kod, prvo, kreira varijable za poslužitelj i korisnika kada se spoji na poslužitelj. Drugo, odabrat će bazu podataka, u ovom slučaju "USERAUTH". Ova datoteka mora biti uključena u "log.php" i "reg.php" za pristup bazi podataka.
PHP kod
//Vaše MySQL korisničko ime$pass = "redere"; //lozinka $conn = mysql_connect ($server, $user, $pass); //spoj na poslužitelj$db = mysql_select_db("userauth", $conn); //odaberite bazu podataka ako (!$db) ( //ako ne može odabrati bazu podataka echo "Oprostite, pogreška:(/>"; //Pokazuje poruku greške Izlaz(); //Omogućuje pokretanje drugih PHP skripti } ?>
Sljedeća je stranica za prijavu, neka se zove “login.php”. Prvo provjerava ima li pogrešaka u unesenim podacima. Stranica ima polja za korisničko ime, lozinku, gumb za slanje i poveznicu za registraciju. Kada korisnik klikne na gumb "Prijava", forma će biti obrađena kodom iz datoteke "log.php", a zatim će se prijaviti.
PHP kod
0) { //ako postoje pogreške sesije$greška = "
" . $msg . " |
Zatim napišemo skriptu za prijavu u sustav. Nazovimo to "log.php". Ima funkciju čišćenja ulaznih podataka od SQL injekcija koje mogu uništiti vašu skriptu. Drugo, prima podatke obrasca i provjerava njihovu ispravnost. Ako su ulazni podaci ispravni, skripta šalje korisnika na stranicu ovlaštenih korisnika, ako nisu, postavlja greške i šalje korisnika na stranicu za prijavu.
PHP kod
//pokreni sesiju snimanja funkcija Fix($str) ( //čišćenje polja $str = trim($str); if (get_magic_quotes_gpc()) ( $str = stripslashes ($str); ) //niz za spremanje grešaka$errflag = netočno; //oznaka pogreške $username = Fix($_POST["username"]); //Korisničko ime$password = Fix($_POST["password"]);//password ) //provjera lozinke if ($password == "") ( $errmsg = "Lozinka nedostaje"; //greška $errflag = istina; //podiže zastavicu u slučaju greške) //ako se pojavi zastavica pogreške, preusmjerava natrag na obrazac za registraciju //bilježi pogreške session_write_close(); //zatvaranje sjednice //preusmjeravanje Izlaz(); )//upit u bazu podataka $qry = "SELECT * FROM `users` WHERE `Username` = "$username" AND `Password` = "" . md5 ($password) . """; $rezultat = mysql_query($qry);//provjeriti je li zahtjev uspješan (ima li podataka na njemu) if (mysql_num_rows ($result) == 1) ( while ($row = mysql_fetch_assoc ($result)) ( $_SESSION["UID"] = $row["UID"];//dobivanje UID-a iz baze podataka i njegovo postavljanje u sesiju $_SESSION["USERNAME"] = $korisničko ime; session_write_close(); //zatvaranje sjednice//postavlja odgovara li korisničko ime onom sesije //preusmjeravanje zaglavlje("lokacija: član.php"); //zatvaranje sjednice) ) else ( $_SESSION["ERRMSG"] = "Nevažeće korisničko ime ili lozinka"; //pogreška session_write_close(); //preusmjeravanje zaglavlje("lokacija: login.php");
Izlaz();
PHP kod
0) { //ako postoje pogreške sesije$greška = "
" . $msg . " |
Sada ćemo kreirati skriptu za registraciju u datoteci "reg.php". Sadržat će "sql.php" za povezivanje s bazom podataka. Za brisanje polja za unos koristi se ista funkcija kao u skripti za prijavu. Varijable su postavljene za moguće pogreške. Sljedeća je funkcija za stvaranje jedinstvenog identifikatora koji nikada prije nije bio dan. Podaci iz obrasca za registraciju se potom izdvajaju i provjeravaju. Provjerava se da je adresa e-pošte u ispravnom formatu i da je lozinka ponovno ispravno unesena. Skripta zatim provjerava postoji li korisnik s istim imenom u bazi podataka i, ako postoji, prijavljuje pogrešku. Na kraju, kod dodaje korisnika u bazu podataka.
PHP kod
//pokreni sesiju snimanja funkcija Fix($str) ( //brisanje polja $str = @trim($str); if (get_magic_quotes_gpc()) ( $str = stripslashes ($str); ) vrati mysql_real_escape_string($str); ) $errmsg = niz(); //niz za spremanje grešaka$errflag = netočno; //oznaka pogreške $UID = "12323543534523453451465685454";//jedinstveni ID $username = Fix($_POST["username"]); //Korisničko ime$e-pošta = $_POST["e-pošta"]; //E-pošta $password = Fix($_POST["password"]);//lozinka $rpassword = Fix($_POST["rpassword"]);//ponovi lozinku //provjeri korisničko ime if ($username == "") ( $errmsg = "Korisničko ime nedostaje"; //greška $errflag = true ; //podiže zastavu u slučaju greške) //provjeri e-poštu if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@+(\.+)*(\.(2,3 ))$", $email)) ( //mora odgovarati formatu: [e-mail zaštićen]$errmsg = "Nevažeća e-pošta"; //pogreška $errflag = istina ; //podiže zastavu u slučaju greške } //provjera lozinke if ($password == "") ( $errmsg = "Lozinka nedostaje"; //greška $errflag = true ; //podiže zastavu u slučaju greške } //provjera ponavljanja lozinke if ($rpassword == "") ( $errmsg = "Nedostaje ponovljena lozinka";//greška $errflag = true ; //podiže zastavu u slučaju greške } //provjeri valjanost lozinke if (strcmp($password, $rpassword) != 0) ( $errmsg = "Lozinke se ne podudaraju";//greška $errflag = istina; //podiže zastavu u slučaju greške } //provjeri je li korisničko ime dostupno if ($username != "") ( $qry = "SELECT * FROM `users` WHERE `Username` = "$username""; //upit u MySQL $result = mysql_query ($qry); if ($result) ( if (mysql_num_rows ($result) > 0) ( //ako je ime već u upotrebi$errmsg = "Korisničko ime već u upotrebi"; //poruka pogreške$errflag = točno; //podiže zastavu u slučaju greške) mysql_free_rezultat($rezultat); ) ) //ako podaci nisu potvrđeni, preusmjerava natrag na obrazac za registraciju if ($errflag) ( $_SESSION["ERRMSG"] = $errmsg; //poruka pogreške session_write_close(); //zatvaranje sjednice zaglavlje("lokacija: registar.php"); //preusmjeravanje Izlaz(); //dodavanje podataka u bazu podataka$qry = "INSERT INTO `userauth`.`users`(`UID`, `Korisničko ime`, `Email`, `Password`) VALUES("$UID","$username","$email","" . md5 ($lozinka) """); $rezultat = mysql_query($qry); //provjerite je li zahtjev za dodavanjem bio uspješan if ($rezultat) ( echo "Hvala na registraciji, " .$korisničko ime." Molimo prijavite se ovdje"; izlaz (); ) else ( die ("Pogreška, provjerite ponovno kasnije"); ) ?>
Također morate izraditi skriptu za odjavu korisnika sa sustava. Prekida sesiju za korisnika s danim jedinstvenim ID-om i imenom, a zatim preusmjerava korisnika na stranicu za prijavu.
PHP kod
Konačno, skripta "auth.php" može se koristiti kako bi stranice bile dostupne samo ovlaštenim korisnicima. Provjerava podatke za prijavu i, ako su točni, omogućuje korisniku pregledavanje stranica, a ako nisu, traži od njega da se prijavi. Osim toga, ako netko pokuša hakirati stranicu stvaranjem jedne od sesija, ona će biti prekinuta, kao iu općem slučaju.
PHP kod
Jedan od uvjeta u gornjem kodu predmet je pitanja u .
Sljedeći kod je potrebno ubaciti na stranicu za ovlaštene korisnike, zove se npr. “member.php”, ali vaš se može zvati kako god želite.
PHP kod
Ovlašteni ste za pristup ovoj stranici. izađi van ( )
Autentifikacija korisnika je spremna!
Moguće je koristiti funkciju Zaglavlje() poslati poruku "Potrebna provjera" preglednik, prisiljavajući ga da prikaže prozor za unos vaše prijave i lozinke. Nakon što korisnik ispuni korisničko ime i lozinku, poveznica koja sadrži PHP skriptu bit će ponovno pozvana s unaprijed definiranim varijablama PHP_AUTH_USER, PHP_AUTH_PW i AUTH_TYPE postavljenim na prijavu, lozinku i vrstu provjere autentičnosti. Ove unaprijed definirane varijable pohranjene su u nizovima $_SERVER i $HTTP_SERVER_VARS. Podržane su obje vrste: "Basic" i "Digest" (od PHP 5.1.0). Pogledajte funkciju za detalje Zaglavlje().
Primjer fragmenta skripte koji prisiljava klijenta da se prijavi za pregled stranice:
Primjer #6 Osnovni primjer HTTP provjere autentičnosti
if (!isset($_SERVER [ "PHP_AUTH_USER" ])) (
Zaglavlje( "WWW-Authenticate: Basic realm="My Realm"");
jeka "Poslana poruka kada
ako je korisnik kliknuo gumb Odustani";
Izlaz;
) inače (
jeka"
Pozdrav ($_SERVER [ "PHP_AUTH_USER" ]).
" ;jeka "
Unijeli ste lozinku
( $_SERVER [ "PHP_AUTH_PW" ]) ." ;}
?>
Primjer #7 Primjer sažete HTTP provjere autentičnosti
Ovo je primjer implementacije jednostavne Digest HTTP skripte za provjeru autentičnosti. Za detalje pogledajte » RFC 2617.
$realm = "Zabranjena zona" ;
//korisnik => lozinka
$users = array("admin" => "mypass" , "guest" => "guest" );
if (prazno($_SERVER [ "PHP_AUTH_DIGEST" ])) (
zaglavlje ("HTTP/1.1 401 neovlašteno");
Zaglavlje( "WWW-Authenticate: Digest realm="". $područje.
"",qop="auth",nonce="" . uniqid(). "", neproziran="" . md5 ($područje). """ );
Umrijeti( "Tekst se šalje ako korisnik klikne Odustani");
}
// analizirati PHP_AUTH_DIGEST varijablu
if (!($data = http_digest_parse ($_SERVER [ "PHP_AUTH_DIGEST" ])) ||
!isset($users [ $data [ "username" ]]))
umrijeti( "Krivi podaci!");
// generiraj točan odgovor
$A1 = md5 ($data [ "username" ] . ":" . $realm . ":" . $users [ $data [ "username" ]]);
$A2 = md5($_SERVER["REQUEST_METHOD"]. ":" . $data["uri" ]);
$valid_response = md5 ($A1 . ":" . $data [ "nonce" ]. ":" . $data [ "nc" ]. ":" . $data [ "cnonce" ]. ":" . $data [ "qop" ].
if ($data [ "response" ] != $valid_response )
umrijeti( "Krivi podaci!");
// ok, prijava i lozinka su točni
echo "Prijavljeni ste kao: " . $podaci["korisničko ime"];
// Funkcija analize zaglavlja http auth
funkcija http_digest_parse ($txt)
{
// zaštita od podataka koji nedostaju
$needed_parts = array("nonce" => 1, "nc" => 1, "cnonce" => 1, "qop" => 1, "username" => 1, "uri" => 1, "response" => 1);
$podaci = polje();
$keys = implode ("|", array_keys ($needed_parts ));
Preg_match_all ("@(" . $ključevi . ")=(?:([\""])([^\2]+?)\2|([^\s,]+))@", $txt , $podudaranja , PREG_SET_ORDER );
Foreach ($ odgovara kao $m) (
$podaci [$m [1]] = $m [3]? $m [3] : $m [4];
poništi($potrebni_dijelovi [ $m [ 1 ]]);
}
Vratiti $needed_parts? lažno: $podaci;
}
?>
Komentar: Napomena o kompatibilnosti
Budite posebno oprezni kada navodite HTTP zaglavlja. Kako bi se osigurala maksimalna kompatibilnost s najvećim brojem različitih klijenata, riječ "Basic" mora biti napisana velikim slovom "B", regija (realm) mora biti u dvostrukim (ne jednostrukim!) navodnicima, a ispred mora biti točno jedan razmak kod 401 u naslovu HTTP/1.0 401. Parametri provjere autentičnosti moraju biti odvojeni zarezima, kao što je prikazano u gornjem primjeru provjere autentičnosti sažetka.
Umjesto jednostavnog prikazivanja varijabli PHP_AUTH_USER i PHP_AUTH_PW na ekranu, možda ćete morati provjeriti jesu li ispravne. Da biste to učinili, upotrijebite upit baze podataka ili potražite korisnika u dbm datoteci.
Možete promatrati značajke rada preglednika Internet Explorer. Vrlo je izbirljiv u pogledu parametara odaslanih zaglavlja. Trik s naslovom WWW-Autentifikacija prije slanja statusa HTTP/1.0 401 radi za njega do sada.
Od PHP 4.3.0, kako bi se spriječilo da netko napiše skriptu koja otkriva lozinku za stranicu koja koristi vanjsku provjeru autentičnosti, varijable PHP_AUTH nisu postavljene ako stranica koristi vanjsku provjeru autentičnosti i ako je postavljena na siguran način rada. Međutim, varijabla REMOTE_USER može se koristiti za provjeru autentičnosti eksterno ovjerenog korisnika. Dakle, uvijek možete koristiti varijablu $_SERVER["REMOTE_USER"].
Komentar: Napomena o konfiguraciji
PHP koristi indikaciju direktive AuthType za označavanje koristi li se vanjska provjera autentičnosti ili ne.
Treba napomenuti da sve navedeno ne sprječava krađu lozinki stranicama koje zahtijevaju autorizaciju od strane nekoga tko neovlašteno kontrolira stranice koje se nalaze na istom serveru.
I Netscape Navigator i Internet Explorer brišu autentifikacijsku predmemoriju trenutnog prozora za određeno područje kada su primljeni od poslužitelja. Ovo se može koristiti za prisiljavanje korisnika da se odjavi i ponovno prikaže dijaloški okvir korisničkog imena i lozinke. Neki programeri koriste ovo za vremensko ograničenje prijava ili davanje gumba za odjavu.
Primjer #8 Primjer HTTP autentifikacije s prisilnim unosom novog para prijava/lozinka
funkcija authenticate() (
Zaglavlje( "WWW-Authenticate: Basic realm="Test Authentication System"");
zaglavlje ("HTTP/1.0 401 neovlašteno");
jeka "Morate unijeti ispravno korisničko ime i lozinku da biste dobili pristup resursu \n";
Izlaz;
}
if (!isset($_SERVER [ "PHP_AUTH_USER" ]) || dobrodošli:"
($_POST [ "SeenBefore" ] == 1 && $_POST [ "OldAuth" ] == $_SERVER [ "PHP_AUTH_USER" ])) (
ovjeri();
) inače (
jeka "
"
;
jeka "Prethodna prijava: ". htmlspecialchars($_REQUEST["OldAuth"]);
jeka ";
jeka "\n";
jeka ". htmlspecialchars($_SERVER["PHP_AUTH_USER"]) . "\" />\n" ;
jeka "\n";
jeka "
}
?>
Ovo ponašanje nije regulirano standardima HTTP Basic-autentifikacija, stoga ne biste trebali ovisiti o njoj. Testiranje preglednika Ris pokazao da Ris ne briše autorizacijsku predmemoriju kada primi status 401 od poslužitelja, a klikom na “Natrag” i zatim “Naprijed” u nizu, moguće je otvoriti takvu stranicu, pod uvjetom da traženi atributi autorizacije nisu promijenjeni. Međutim, korisnik može pritisnuti tipku "_" za brisanje predmemorije za provjeru autentičnosti.
Također treba napomenuti da prije PHP-a 4.3.3, HTTP provjera autentičnosti nije radila na poslužiteljima koji pokreću Microsoft IIS ako je PHP bio instaliran kao CGI modul, zbog nekih IIS ograničenja. Kako bi ispravno radio u PHP-u 4.3.3+, morate urediti postavku konfiguracije IIS-a pod nazivom " Sigurnost imenika". Kliknite na natpis " Uredi" i postavite opciju " Anonimni pristup", sva ostala polja trebaju ostati neoznačena.
Još jedno ograničenje ako koristite IIS putem ISAPI i PHP 4: varijable PHP_AUTH_* nisu definirani, ali je u isto vrijeme varijabla dostupna HTTP_AUTHORIZATION. Primjer koda koji možete koristiti: popis($user, $pw) = explode(":", base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)));
Komentar: Napomena u vezi s IIS-om:
Kako bi HTTP provjera autentičnosti radila ispravno u IIS-u, u PHP konfiguraciji opcija cgi.rfc2616_headers mora biti postavljena na 0 (zadana vrijednost).
Komentar:
U slučaju da se koristi sigurni način rada, UID trenutne skripte bit će dodan carstvo- dio zaglavlja WWW-Autentifikacija.
Ponekad ga je potrebno zatvoriti od vanjskog pristupa PHP stranicu ako pravite zatvoreni dio stranice. To mogu biti neke skrivene informacije za vaše klijente ili posjetitelje stranice, neka vrsta administrativnog sučelja za vas itd. Možete smisliti stotine različitih zadataka koji zahtijevaju ograničenja pristupa.
Takvu stranicu možete zatvoriti na nekoliko komplementarnih načina:
- Zaštita lozinkom (login/lozinka) pomoću varijabli $_SERVER["PHP_AUTH_USER"] I $_SERVER["PHP_AUTH_PW"].
- Zaštita od strane IP adresa klijenta pomoću varijable $_SERVER["REMOTE_ADDR"].
- Zaštita od strane MAC adresa u lokalnim mrežama (pored zaštite od strane IP).
Pogledajmo prvo prvu metodu, koja je glavna. Omogućuje vam da blokirate pristup stranici koristeći svoju prijavu i lozinku, tako da samo osobe koje znaju prijavu i lozinku mogu dobiti pristup. Osim toga, mogu se podijeliti prema ovom kriteriju i, u skladu s tim, mogu se dati različite informacije za svaku. Implementirano izdavanjem posebnih polja u zaglavlju protokola HTTP. Kreirajmo funkciju auth_send():
" ,"
Pogreška provjere autentičnosti
" ,"Obratite se administratoru kako biste dobili svoju prijavu i lozinku.
" ,""; izlaz; ); ?>Ova funkcija obavještava preglednik da pristup zahtijeva autorizaciju pomoću prijave i lozinke. I također prikazuje stranicu u HTML za korisnika.
" ,"
Dobrodošli!
" ,"Prijavljeni ste pomoću prijave ",$auth_user," i lozinke ",$auth_pass,".
" ,""; ?>
Kôd za potvrdu prijave i lozinke u ovom slučaju nije previše kompliciran, budući da se implementira za jednu osobu. Logika rada je jednostavna ako nema varijable $_SERVER["PHP_AUTH_USER"] I $_SERVER["PHP_AUTH_PW"] ili njihove vrijednosti ne odgovaraju traženim, tada pozovite funkciju auth_send(). Ne zaboravite da na kraju zove Izlaz, pa se izvođenje programa zaustavlja.
Sljedeća razina zaštite implementirana je filtriranjem IP adrese klijenta koji se povezuje. Naravno, na internetu, mnogi pružatelji izdaju IP privremene adrese i ova zaštita je beskorisna, ali ako govorimo o korporativnim lokalnim mrežama, onda će ova provjera pružiti dodatnu zaštitu.
Vaš IP nije pronađen!!!"; izlaz; ); ?>
Ovdje u redu $allowed_ips označeni razdvojeni razmacima IP adrese kojima je dopušten pristup. Zatim dobivamo niz pomoću eksplodirati() i potražite adresu klijenta od $_SERVER["REMOTE_ADDR"]. Koristio sam funkciju za pretraživanje pretraživanje_niza(), budući da je malo vjerojatno da će njegov kod implementiran u C-u raditi nešto brže od onoga što možemo napisati u PHP pomoću petlji za ili za svakoga. Ali brzina ovdje nije glavna :)
I posljednji korak zaštite je provjera MAC adrese. Klasificira se kao paranoičan i trebao bi se koristiti ako pristupate s lokalne mreže, a podaci koje štitite su zaista vrlo važni. Do sada sam implementirao ovu provjeru samo na sustavu Linux, zbog relativne jednostavnosti implementacije. Ali možete ga pokušati implementirati za bilo koju drugu platformu. Napišemo funkciju:
Kao što su korisnici Linuxa već shvatili, temelji se na ARP tablica sustava, kojoj se može pristupiti pomoću datoteke /proc/net/arp. Funkcija traži tražene nizove IP adresu i vraća je MAC adresa:
Vaš IP=192.168.10.15 i MAC=00:04:31:E4:F8:37
U sustavu Windows Možda postoje i neki načini za dobivanje MAC jednostavniji, ali od onih koji stvarno rade, ovo je zaključak ARP sistemske tablice naredbom:
C:\WINDOWS\>arp -a sučelje: 192.168.10.15 na sučelju 0x1000003 IP adresa Tip fizičke adrese 192.168.10.1 00-50-22-b0-6a-aa dinamički 192.168.10.2 00-0f-38-68-e9- e8 dinamički 192.168.10.3 00-04-61-9e-26-09 dinamički 192.168.10.5 00-0f-38-6a-b1-18 dinamički
Možete sami implementirati zaštitu temeljenu na ovoj adresi ako vam je stvarno potrebna :) Ali zapamtite da ako na mreži imate neupravljanu opremu bez mogućnosti vezanja MAC adrese na port, ova zaštita možda neće raditi jer svi vaši identifikacijski podaci korišteni za zaštitu (prijava, lozinka, IP i MAC adresa) mogu biti krivotvoreni.