Hoe om `n veilige aanmeldskrip in PHP en MySQL te skep
Met meer en meer stories van piracy in die nuus, is ontwikkelaars op soek na beter maniere om hul webwerf te beveilig. As u webwerf `n lidmaatskap het, kan dit gekraak word en gebruikersdata kan in gevaar gestel word. Hierdie gids sal jou `n poging om `n veilige login met PHP te skep, wys. Ons het ons bes gedoen om die kode te programmering, maar sekuriteit en veral enkripsie is komplekse probleme wat die hele tyd verander, en ons kan nie sê dat ons al die veld oorheers nie. Daarom kon ons `n paar truuks in ons programmering gemis het. Indien wel, laat ons weet en ons sal probeer om enige verbetering aan te bring wat ons het.
Na aanleiding van hierdie gids sal u help om baie soorte aanvalle wat krakers gebruik om beheer van ander gebruikers se rekeninge te beheer, rekeninge te verwyder en / of data te verander. Hier volg `n lys van moontlike aanvalle waarvan hierdie gids hulself probeer verdedig:
conținut
- Dinge wat jy nodig het
- Stappe
- Deel 1stel jou bediener op
- Deel 2stel die mysql databasis op
- Deel 3skep die verbindingsbladsy vir die databasis
- Deel 4skep php funksies
- Deel 5skep verwerkingsbladsye
- Teken in met ons
- Deel 6skep jаvascript lêers
- Deel 7skep html-bladsye
- Suksesvolle registrasie!
- Daar was `n probleem.
- Deel 8beskerm bladsye
- Wenke
- Waarskuwings
Die benadering is om `n kombinasie van data filters, enkripsie en ander metodes te gebruik om die lewe `n bietjie harder te maak vir diegene wat dink dat jy jou aanval.
Ons probeer om voortdurend die huidige skrif te verbeter. die nuutste weergawe van die kode is beskikbaar in GitHub. Daar kan verskille wees tussen die kode wat u op hierdie bladsy aflaai en die kode wat in hierdie artikel aangehaal word. U moet in gedagte hou dat ons doelwit nie was dat die aanbieding van HTML-bladsye wat deur die aansoek gemaak is, mooi lyk nie.
U moet ook in gedagte hou dat ons nie PHP-etikette sluit in lêers wat slegs PHP-kode bevat nie. Dit is in lyn met die meeste kodeformaat aanbevelings.
Ten slotte is dit nodig om te weet dat ons u versoek om al die nie-HTML-lêers van die aansoek in verskillende dopgehou in die hoofmap van die aansoek te skep. Die maklikste manier om die korrekte gidsstruktuur te skep, is om die mees onlangse kode af te laai deur op een van die bogenoemde skakels te kliek.
Gebruik asseblief hierdie aansoek as basis vir u eie implementering, maar gebruik dit nie as `n voorbeeld van goeie programmeringspraktyk nie.
Dinge wat jy nodig het
Omdat ons mysqli_ * sal gebruik wat `n stel PHP-klasse is om toegang tot ons mySQL-databasis te kry, sal u die volgende weergawes van PHP en MySQL nodig hê.
- PHP weergawe 5.3 of later
- MySQL weergawe 4.1.3 of later
Uiteraard sal u ook `n webbediener moet hê wat opgestel is om PHP te gebruik om u bladsye te host. Dit sal waarskynlik die webbediener wees wat u bladsy aanbied, tensy u self die webwerf aanbied.
Om die PHP en MySQL-weergawe op u bediener te monitor, gebruik die funksie phpinfo () -.
stappe
Deel 1
Stel jou bediener op
Die meeste van die hosting dienste het reeds PHP en mySQL geïnstalleer, maar u moet seker maak dat hulle die nuutste weergawes van PHP en mySQL het sodat hierdie gids van hulp kan wees. As jy nie ten minste PHP5.3 en MySQL5 het nie, kan jy hul verbintenis tot sekuriteit bevraagteken. As u u sagteware opgedateer het, is dit deel van die sekuriteitsproses.
As u u eie bediener of rekenaar het, moet u die sagteware wat normaalweg volgens u stelsel vereis word, installeer. Oor die algemeen, as jy nie die konfigurasie vir produksie redes gaan gebruik nie en jy gaan ontwikkel in Windows of OS X, sal die installering van `n aansoekpakket (stapel) XAMPP aanbeveel word. Kry die toepaslike weergawe vir u bedryfstelsel in:
https://apachefriends.org/en/xampp.html
Hou egter in gedagte dat u XAMPP onder geen omstandighede moet gebruik om `n produksie-bedieneromgewing te skep nie.
In Linux, gebruik die pakketbestuurder om die nodige pakkette te laai en te installeer. Sommige verspreidings, soos Ubuntu, bevat al die nodige toepassings in `n enkele pakket. Jy moet net die volgende doen in `n Ubuntu-terminaal:
sudo apt-installeer lamp-bediener ^ phpmyadmin
Maar selfs as jy die nodige elemente installeer, maak seker MySQL instel met `n veilige wortel wagwoord.
Deel 2
Stel die MySQL databasis op
Begin die sessie in u databasis as `n administrateur gebruiker (gewoonlik "root").
In hierdie gids sal ons `n databasis genaamd "safe_home" skep.
Kyk hoe skep `n databasis in phpMyAdmin.
U kan die onderstaande kode gebruik of dieselfde doen in phpMyAdmin of in u gunsteling MySQL GUI-kliënt, as u wil:
CREATE DATABASE `secure_login`-
Deur `n gebruiker met beperkte regte te skep, beteken dat as die sekuriteit ooit in u skrip geskend word, sal die hacker niks van ons databasis kan verwyder of verlaat nie. Deur hierdie gebruiker te gebruik, kan jy byna wat jy wil met jou aansoek doen. As jy regtig paranoïes is, skep `n ander gebruiker vir elke funksie.
Uiteraard moet u by MySQL aanmeld as `n gebruiker met voldoende regte om `n ander gebruiker te kan skep. Gewoonlik sal hierdie gebruiker wortel wees.
Die volgende besonderhede is van die gebruiker wat ons geskep het:
Nota: ons beveel aan om die wagwoord wat ons voorheen genoem het, te verander wanneer u dit op u eie bediener gaan uitvoer. As jy dit doen, maak seker dat jy ook die onderstaande kode en die koppelingskode van die PHP-databasis in die aansoek wat ons sal skep, verander.
Onthou dat dit nie `n wagwoord moet wees wat jy kan onthou nie, maak dit so ingewikkeld as moontlik. Byvoorbeeld, dit is `n willekeurige wagwoordgenerator.
Dan sal daar ook die SQL-kode wees om die databasis gebruiker te skep en aan hom die nodige toestemmings te gee. As jy verkies, kan jy dit ook doen in `n GUI databasis kliënt soos phpmyadmin:
SKEP gebruiker sec_user `@` localhost `identified by` eKcGZr59zAa2BEWU`-GRANT te kies, INSERT, UPDATE OP `secure_login`. * OM `sec_user` @ `localhost`-
As jy sien dat jy die verwydering van rekords van enige van die tafels van hierdie module, moet jy voeg VERWYDER by die lys van voorregte of anders wat jy kan `n ander gebruiker wat net die voorreg skrap en net in die tabel wat jy wil rekords as skrap skep jy wil dit nie in albei. Dit is nie nodig dat u die EINDE-voorreg ten alle tye vir die huidige skripvoorbeeld gee nie.
Die onderstaande kode sal `n tabel skep met vyf velde (identifikasie, gebruikersnaam, e-pos, wagwoord, sout). Ons sal die CHAR data tipe gebruik vir die velde waarvan ons uitbreiding bekend is, aangesien die velde "wagwoord" en "sout" altyd 128 karakters lank sal wees. Die gebruik van CHAR in daardie gevalle sal die verwerkingskrag red:
CREATE TABLE `secure_login`.`members` (` id` INT PRIMÊRE NIE KEY NULL AUTO_INCREMENT: username` VARCHAR (30) NIE NULL: email` VARCHAR (50) NIE NULL: password` CHAR (128) NIE NULL, `sout` CHAR (128) NIE NULL) MOTOR = InnoDB-
Soos ons reeds genoem het, kan u dit doen in enige tipe kliënt wat u verkies.
Ons sal hierdie tabel gebruik om `n gebruiker se aanmeldpogings te stoor. Dit is `n manier om moeilike geweld aanvalle moeilik te maak:
CREATE TABLE `secure_login`.`login_attempts` (` user_id` INT (11) NIE NULL, `tyd` VARCHAR (30) NIE NULL) MOTOR = InnoDB
Dit sal belangrik wees om die aanmeldskrip te toets, sodat ons die skrip sal aanbied om `n gebruiker met bekende besonderhede te skep:
Die kode wat jy nodig het om in te teken as hierdie gebruiker is:
Voeg in `secure_login`.`members` WAARDES (1, `test_user`, `[email protected]`, `00807432eae173f652f2064bdca1b61b290b52d40e429a7d295d76a71084aa96c0233b82f1feac45529e0726559645acaed6f3ae58a286b9f075916ebf66cacc`, `f9aab579fc1b41ed0c44fe4ecdbfcdb4cb99b9023abb241a6db833288f4eea3c02f76e0d35204a8695077dcf81932aa59006423976224be0390395bae152d4ef`) -
Deel 3
Skep die verbindingsbladsy vir die databasis
Skep `n lêer met die naam "sluit" in die hoofmap van die program en skep dan `n nuwe PHP-lêer in die gids. Plaas die naam "psl-config.php". In `n produksiemilieu moet jy daardie lêer en al die ander "insluitende" lêers buite die webwerwe se dokumentwortel opspoor. As u dit doen, wat ons aanbeveel, moet u die "insluit" of die vereiste verklarings so veel as wat nodig is, verander sodat die aansoek die "insluitende" lêers kan vind.
As u hierdie lêers buite die dokumentwortel van die webbediener plaas, kan u lêer nie met `n URL gevind word nie. Dan, in die geval dat iemand die PHP-uitbreiding per ongeluk verlaat het of die lêertoestemmings beskadig het, kan die lêer nie in teks in `n blaaier venster vertoon word nie.
Die lêer sal globale konfigurasie veranderlikes hê. Aspekte soos om iemand te registreer, as dit `n veilige konneksie (HTTPS) is, kan, benewens die besonderhede van die databasis, ook na daardie plek gaan.
php / *** Dit is die login besonderhede van die databasis: * / define ("HOST", "localhost") - / Die hosting wat jy wil koppel om te definieer ("GEBRUIKER", "sec_user") - / / Die gebruikersnaam van die databasedefine ("Wagwoord", "4Fa98xkHVd2XmnfK") - / Die wagwoord van die databasebepaling ("DATABASIS", "secure_login") - / / Die naam van die databasebepaling ("CAN_REGISTER", "enige") -define ("DEFAULT_ROLE", "lid") -define ("SECURE", ONWAAR) - / SLEGS OM TE ONTWIKKEL!
Dit sal die PHP-kode wees wat u sal moet gebruik om aan te sluit by die mySQL-databasis. Skep `n nuwe PHP-lêer genaamd "db_connect.php" in die "includes" gids van die aansoek en voeg die onderstaande kode by. Dan kan jy die lêer op enige bladsy insluit waarin jy met die databasis wil aansluit.
Phpinclude_once `PSL-config.php`- // Sedert functions.php is nie ingesluit $ mysqli = nuwe mysqli (HOST, gebruikers, wagwoord, databasis). -
Deel 4
Skep PHP funksies
Hierdie funksies sal al die verwerking van die konneksieskyf doen. Voeg alle funksies by die bladsy genaamd "functions.php" in die "includes" gids van die aansoek.
PHP sessies het `n reputasie van nie baie veilig, so dit sal belangrik wees nie net sit "session_start () ;" aan die bokant van elke bladsy wat jy wil gebruik vir PHP sessies. Ons sal `n funksie genaamd "sec_session_start ()" skep, en dit sal `n PHP-sessie op `n veilige manier begin. U moet hierdie funksie bo-aan elke bladsy bel waar u toegang tot `n PHP-sessieveranderlike wil hê. As jy regtig bekommerd is oor die sekuriteit en privaatheid van koekies, kyk gerus na die volgende artikel: Hoe om `n veilige sessiebestuurstelsel in PHP en MySQL te skep.
Met hierdie funksie word jou aanmelding script baie veiliger. Dit sal veroorsaak dat die crackers nie meer toegang tot die koekie maak wat die sessie identifiseer met jаvascript (byvoorbeeld in `n XSS-aanval). Op sy beurt sal die funksie session_regenerate_id (), wat die identifikasie van die sessie in elke bladsy laai, regenereer, help om `n sessie-diefstal te voorkom. Nota: as jy HTTPS in jou inskrywing aansoek gaan gebruik, stel die veranderlike "$ secure" na "true". In `n produksiemilieu is dit noodsaaklik dat jy HTTPS gebruik.
Skep `n nuwe lêer genaamd "functions.php" in die "includes" gids van jou aansoek en voeg die onderstaande kode by.
Phpinclude_once `PSL-config.php` sec_session_start-funksie () {$ session_name = `sec_session_id`- // Stel `n persoonlike sessie naam $ veilige = SECURE -. // Dit stop dat jаvascript in staat wees om toegang te verkry tot die identifisering sessie $ httponly = true -. // verplig sessies net gebruik cookies.if (ini_set ( `session.use_only_cookies`, 1) === ONWAAR) {header ("Plek: .. /error.php?err=Maak nie `n veilige sessie inisiatief nie (ini_set)") -exit () -} // Kry die parameters van die huidige koekies. $ koekieParams = session_get_cookie_params () - session_set_cookie_params ($ koekieParams ["leeftyd"], $ koekieParams ["pad"], $ koekieParams ["domein"], $ Veilige, $ httponly) - // Stel die naam sessie ingestel arriba.session_name ($ session_name) -session_start () - // Begin PHP.session_regenerate_id () sessie - // Regenereer sessie, verwyder die vorige . }
Hierdie funksie sal die e-pos en die wagwoord met die databasis vergelyk, en as daar `n wedstryd is, sal dit as waar (waar) verskyn. Voeg hierdie funksie by jou "functions.php" lêer:
funksie login ($ e-pos, $ wagwoord, $ mysqli) {// Die gebruik van voorbereide stellings beteken dat SQL-inspuiting nie moontlik sal wees nie. $ stmt = $ mysqli->berei voor"SELECT ID, gebruikersnaam, wagwoord, soutFROM lede HOE e-pos =? LIMIT 1")) {$ stmt->bind_param (`s`, $ email) - / Sluit aan by `$ email` na die parameter $ stmt->uitvoer () - // Doen die voorbereide soektog. $ stmt->store_result () - / Kry die veranderlikes van die resultaat. $ stmt->bind_result ($ user_id, $ gebruikersnaam, $ db_password, $ sout) - $ stmt->haal () - / Hash die wagwoord met `n enkele sout. $ wagwoord = hash (`sha512`, $ wagwoord. $ sout) -if ($ stmt->NUM_ROWS == 1) {// As die gebruiker bestaan, tjeks of die rekening is gesluit deur vele pogings // conexión.if (checkbrute ($ USER_ID, $ mysqli) == ware) {// Die rekening is bloqueada./ / Stuur die gebruiker `n e-pos u in te lig dat jou rekening is bloqueada.return FALSE-} anders {// Maak seker dat die wagwoord in die databasis // ooreenstem met die wagwoord wat die gebruiker envió.if ($ db_password == $ wagwoord) {// die wagwoord is korrek // Kry die gebruiker agent gebruiker $ user_browser = $ _SERVER [ `HTTP_USER_AGENT`] -. // XSS beskerming omdat dit waarde kan druk $ USER_ID = preg_replace (."/ [^ 0-9] + /", "", $ USER_ID) - $ _ SESSIE [ `USER_ID`] = $ USER_ID -. // XSS beskerming aangesien dit waarde $ username = preg_replace kon druk ("/ [^ a-zA-Z0-9 _ -] + /","", $ Gebruikersnaam) - $ _ SESSIE [ `username`] = $ username - $ _ SESSIE [ `login_string`] = hash ( `sha512`, $ wagwoord $ user_browser) -. // Teken exitosoreturn true-} anders {// Die wagwoord is nie korrek nie. / / Hierdie poging is in die databasis aangeteken. $ Nou = tyd () - $ mysqli->navraag ("INSERT IN login_attempts (user_id, tyd) WAARDES (`$ user_id`, `$ now`)") -return false-}}} else {// Gebruiker bestaan nie. terugkeer vals-}}}
Brute Force Aanvalle vind plaas wanneer `n hacker probeer om toegang tot `n rekening met 1000 verskillende wagwoorde, hetsy willekeurig of uit `n woordeboek. In ons script, as `n gebruiker se rekening nie meer as 5 pogings aanmeld nie, sal hulle rekening geblokkeer word.
Brute Force Aanvalle is moeilik om te voorkom. Om dit te doen, kan jy CAPTCHA toetse gebruik, gebruikersaccounts blokkeer en `n vertraging in mislukte inskrywings byvoeg, sodat die gebruiker nie nog 30 sekondes toegang kan kry nie.
Ons beveel sterk aan om `n CAPTCHA te gebruik. Aangesien ons hierdie funksionaliteit nie in ons voorbeeldkode geïmplementeer het nie, hoop ons om dit gou te doen SecureImage, aangesien dit nie registrasie vereis nie. Jy kan iets beter bekend as reCAPTCHA van Google.
Wat ook al die stelsel wat u besluit om te gebruik, stel ons voor dat u die CAPTCHA-beeld na twee mislukte inskrywings vertoon om die gebruiker onnodig te verhoed.
As die probleem hiermee in die gesig staar, blokkeer die meeste ontwikkelaars die IP-adres na `n sekere aantal mislukte inskrywings. Daar is egter baie gereedskap om die proses te outomatiseer. Dit kan deur `n reeks proxy`s gaan en selfs die IP verander in elke versoek. As u al hierdie IP-adresse sluit, kan u ook die rekeninge van u wettige gebruikers blokkeer. In ons kode sal ons mislukte pogings aanteken en die gebruiker se rekening blokkeer ná vyf onsuksesvolle pogings. Dit sal `n e-pos aan die gebruiker stuur met `n skakel om dit terug te stel, maar ons het hierdie punt nie in ons kode geïmplementeer nie. Dan sal ons die "checkbrute ()" funksie tot op hede aanbied. Voeg dit by jou "functions.php" -kode:
checkbrute funksie ($ USER_ID, $ mysqli) {// Kry die huidige tyd stempel $ = tyd nou () -. // Alle aanlogpogingen getel vanaf 2 uur voor $ valid_attempts = $ nou -. ( 2 * 60 * 60) -if ($ stmt = $ mysqli->berei voor"SELECT timeFROM login_attemptsWHERE user_id =? EN tyd > `$ valid_attempts`")) {$ stmt->bind_param (`i`, $ user_id) - // Voer die voorbereide soektog uit. $ stmt->voer () - $ stmt->store_result () - // As daar meer as 5 aanmelding pogings failed.if ($ stmt->NUM_ROWS > 5) {return true-} anders {terugkeer vals-}}}
Ons sal dit doen deur te kyk na "user_id" en die sessie veranderlikes "login_string". Die SESSION-veranderlike "login_string" het die inligting van die gebruiker se blaaier tesame met die wagwoord gekoppel deur `n hash-funksie. Ons gebruik die inligting van die blaaier, aangesien dit baie onwaarskynlik is dat die gebruiker dit in die middel van die sessie sal verander. Dit sal help om `n sessie diefstal te voorkom. Voeg hierdie funksie by jou "functions.php" -lêer in die "insluitende gids" van jou aansoek:
funksie login_check ($ mysqli) {// Kyk of al sessie veranderlikes is configuradas.if (isset ($ _ SESSIE [ `USER_ID`], $ _ SESSIE [ `username`], $ _ SESSIE [ `login_string`])) {$ USER_ID = $ _SESSION [ `USER_ID`] - $ login_string = $ _SESSION [ `login_string`] - $ username = $ _SESSION [ `username`] - // Kry die gebruiker agent string gebruiker $ user_browser = $ _SERVER [. `HTTP_USER_AGENT`] - as ($ stmt = $ mysqli->berei voor"SELECT passwordFROM membersWHERE id =? BEPERK 1")) {// Sluit aan by $ $ user_id by die parameter. $ Stmt->bind_param (`i`, $ user_id) - $ stmt->uitvoer () - // Doen die voorbereide soektog. $ stmt->store_result () - if ($ stmt->num_rows == 1) {// As die gebruiker bestaan, verkry hy die veranderlikes van die resultaat. $ stmt->bind_result ($ wagwoord) - $ stmt->haal () - $ login_check = hash (. `sha512`, $ wagwoord $ user_browser) -As ($ login_check == $ login_string) {// Nou online !! terugkeer true-} anders {// Geen conectado.return FALSE-}} anders {// Geen conectado.return FALSE-}} anders {// Geen conectado.return FALSE-}} anders {// Geen conectado.return FALSE- }}
Hierdie funksie maak die uitvoer van die PHP_SELF bediener veranderlike skoon. Dit is `n wysiging van `n funksie van dieselfde naam wat gebruik word deur die WordPress-inhoudbestuurstelsel:
funksie esc_url ($ url) {if (`` == $ url) {retour $ url -} $ url = preg_replace (`| [^ a-z0-9- ~ + _.?&-, /:% @ $ | * `() X80 - xff] | i`, ``, $ url) - $ strook = array ( `% 0D ","% 0A ","% 0D ","% 0A `) - $ url = (string) $ URL-$ tel = 1-terwyl ($ telling) {$ url = str_replace ($ strook,` `, $ url, $ telling) -} $ url = str_replace ( `- //` `: //`, $ url) - $ url = htmlentities ($ url) - $ url = str_replace ( `&- `,` 038- `, $ url) - $ url = str_replace ("`", ` 039- `!, $ Url) -As ($ url [0] ==` / `) {// ons is geïnteresseerd net relatiewe skakels $ _SERVER [` PHP_SELF `] terugkeer` `-} anders {terugkeer $ url -}}
Die probleem met die gebruik van `n ongefilterde bediener veranderlike is dat dit gebruik kan word in kruis-site scripting aanvalle. Volgens die meeste verwysings, jy hoef net deursyfer "htmlentities ()", is egter steeds onvoldoende is, so is daar oormatige sekuriteitsmaatreëls vir hierdie funksie.
Ander stel voor dat die aksie-kenmerk van die vorm leeg gelaat word of dit na `n leë string moet plaas. Maar dit kan lei tot a klik ontvoering aanval iframe.
Deel 5
Skep verwerkingsbladsye
Skep `n lêer om die aanmeldings te verwerk, met die naam "process_login.php", in die "includes" gids van die program. Jy sal na hierdie gids moet gaan, want dit het geen HTML-formaat nie.
Ons sal die PHP funksies reeks mysqli_ * gebruik, aangesien dit een van die mees opgedateerde mySQL uitbreidings is.
Phpinclude_once `db_connect.php`-include_once` functions.php`-sec_session_start () - // Ons veilige persoonlike login PHP.if (isset ($ _ POST [ `n e-pos `], $ _POST [` p `]) ) {$ e = $ _POST [ `n e-pos `] - $ wagwoord = $ _POST [` p `] - // wagwoord met hashif (login ($ e-pos, $ wagwoord, $ mysqli) == ware) {// Start van exitosaheader sessie ( `Location: ../protected_page.php`)-} anders {// Begin sessie exitosaheader (` Location: ../index.php?error=1`)-}} anders {// veranderlikes POST korrek is nie na hierdie bladsy gestuur nie.echo `Ongeldige versoek`-}
Die sessie-sluitingsskrif moet aanmeld, dit vernietig en dan na `n ander plek herlei. Nota: ons beveel aan om `n CSRF-beskerming by te voeg as iemand daarin slaag om `n verborge skakel na hierdie bladsy te stuur. Vir meer inligting oor CSRF, besoek Kodering Horror.
Die huidige kode om die gebruiker te ontkoppel, wat jy moet byvoeg by die lêer met die titel "logout.php" in die "includes" gids van die program, is soos volg:
Phpinclude_once `sluit / functions.php`-sec_session_start () - // unconfigures al sessie waardes $ _ SESSIE = array () -. // Kry sessie parameters $ params = session_get_cookie_params () -. // verwyder die koekie current.setcookie (session_name (), ``, time () - 42000, $ params ["pad"], $ params ["domein"], $ params ["verseker"], $ params ["httponly"]) / / Vernietig sessie. session_destroy () - header (`Location: .. / index.php`) -
U moet die registrasiekode in twee nuwe lêers, genaamd "register.php", in die wortelgids van die aansoek en "register.inc.php" in die "includes" gids insluit, wat die volgende sal doen:
Die meeste van die validering word gedoen in jаvascript, aan die kant van die kliënt. Dit is omdat die gebruiker nie die motivering het om hierdie verifikasies te omseil nie. Hoekom wil die gebruiker `n rekening skep wat nie so veilig sou wees nie? Ons sal praat oor jаvascript in die volgende afdeling.
Vir nou sal jy net die lêer "register.php" moet skep en die onderstaande kode insluit:
phpinclude_once `includes / register.inc.php`-include_once` includes / functions.php`-?>Veilige Login: Registrasievorm Teken in met ons
phpif (! leeg ($ error_msg)) {echo $ error_msg-}?>
- Gebruikers name mag slegs syfers, hoofletters, kleinletters en onderstrepe bevat.
- Die e-posse moet `n geldige formaat hê.
- Wagwoorde moet ten minste 6 karakters bevat.
- Wagwoorde moet saamgestel word uit:
- Ten minste een hoofletter (A-Z)
- Ten minste een kleinletter (a-z)
- Ten minste een nommer (0-9)
Die wagwoord en bevestiging moet presies ooreenstem. Terug na die login bladsy.
Die lêer "register.inc.php" in die "includes" gids moet die onderstaande kode hê:
phpinclude_once `db_connect.php`-include_once` psl-config.php `- $ error_msg = ""-As (isset ($ _ POST [ `username`], $ _POST [ `n e-pos `], $ _POST [` p `])) {// Sanear en die data te valideer voorsien. $ username = filter_input (INPUT_POST,` username ` , FILTER_SANITIZE_STRING) - $ e = filter_input (INPUT_POST, `n e-pos `, FILTER_SANITIZE_EMAIL) - $ e = filter_var ($ e-pos, FILTER_VALIDATE_EMAIL) -As (filter_var ($ e-pos, FILTER_VALIDATE_EMAIL)) {// nie `n geldige e-pos. $ error_msg. = `Die e-posadres wat jy ingevoer het, is nie geldig nie
`-} $ wagwoord = filter_input (INPUT_POST,` p `, FILTER_SANITIZE_STRING) -As (StrLen ($ wagwoord) = 128) {// Die hashed wagwoord moet 128 caracteres.// Andersins, baie skaars wees Dit sal gebeur het. $ error_msg. = `Ongeldige wagwoordkonfigurasie.
`-} // geldigheid van die gebruiker naam en wagwoord nagegaan is in die cliente.// Dit sal genoeg wees, want niemand sal baat vind by die oortreding van hierdie reglas.//$prep_stmt // = "SELECT ID VAN lede WAAR e-pos =? BEPERK 1"- $ stmt = $ mysqli->Berei voor ($ prep_stmt) - // Kyk die bestaande e-pos. as ($ stmt) {$ stmt->bind_param (`s`, $ email) - $ stmt->voer () - $ stmt->store_result () - if ($ stmt->num_rows == 1) {// Nog `n gebruiker bestaan reeds met hierdie e-pos. $ error_msg. = ``N Gebruiker met hierdie e-posadres bestaan reeds.
`- $ stmt->sluit () -} $ stmt->sluit () -} anders {$ error_msg. = `Databasis fout Lyn 39
`- $ stmt->sluit () -} / / Verifieer die bestaande gebruikersnaam. $ prep_stmt = "SELECT ID VAN lede WAAR gebruikersnaam =? BEPERK 1"- $ stmt = $ mysqli->Berei voor ($ prep_stmt) -if ($ stmt) {$ stmt->bind_param (`s`, $ gebruikersnaam) - $ stmt->voer () - $ stmt->store_result () - if ($ stmt->num_rows == 1) {// Nog `n gebruiker bestaan reeds met hierdie gebruikersnaam. $ error_msg. = ``N Gebruiker met hierdie gebruikersnaam bestaan reeds
`- $ stmt->sluit () -} $ stmt->sluit () -} anders {$ error_msg. = `Databasis foutlyn 55
`- $ stmt->naby () -} // Hangende: // ons moet dit ook oorweeg om die situasie waarin die gebruiker nie // regte te registreer het, te verifieer watter tipe gebruiker probeer om uit te voer operación.if // (leë ($ ERROR_MSG)) {// Skep `n sout aleatoria.//$random_salt = hash ( `sha512, uniqid (openssl_random_pseudo_bytes (16), WAAR)) - Het nie werk // $ random_salt = hash (` sha512, uniqid (mt_rand (1 mt_getrandmax ()), waar)) - // Skep `n wagwoord met sout. $ Wagwoord = hash ( `sha512`, $ wagwoord $ random_salt.) - // Voeg die nuwe gebruiker om die databasis. as ($ insert_stmt = $ mysqli->berei voor"INSERT AAN lede (gebruikersnaam, e-pos, wagwoord, sout) WAARDES (?,?,?,?)")) {$ insert_stmt->bind_param (`ssss`, $ gebruikersnaam, $ e-pos, $ wagwoord, $ random_salt) - // Doen die navraag prepared.if (! $ insert_stmt->uit te voer ()) {header ( "Plek: ../error.php?err=Registration mislukking: INSERT `) -}} kop (` Location: ./register_success.php`)-}}
As daar geen POST data is wat aan die vorm verskaf word nie, sal die registrasievorm vertoon word. Die stuurknoppie van die vorm noem die jаvascript-funksie "regformhash ()". Hierdie funksie sal die nodige valideringstoetse uitvoer en die vorm stuur wanneer alles korrek is. Ons sal praat oor jаvascript funksies in die volgende afdeling.
As POST-data bestaan, sal sommige tjeks van die bediener gemaak word om hulle skoon te maak en te bekragtig. Wees bewus daarvan dat hierdie verifikasies nog nie voltooi is nie. Sommige van die probleme word genoem in die kommentaar in die lêer. Tot dusver verifieer ons slegs dat die e-pos adres die korrekte formaat het, dat die wagwoord met hash die korrekte uitbreiding het en dat die gebruiker nie probeer om `n reeds geregistreerde e-pos te registreer nie.
As alles reg is, sal die nuwe gebruiker geregistreer word en `n nuwe rekord sal in die ledetabel geskryf word.
Deel 6
Skep jаvascript lêers
Hierdie lêer is `n jаvascript-implementering van die Sha512-hash-algoritme. Ons sal die hash-funksie gebruik sodat die wagwoorde nie in eenvoudige teks gestuur word nie.
U kan die lêer aflaai pajhome.org.uk
(Dit sal ook in die github-bewaarplek gered word).
Stoor jou kopie van hierdie lêer in `n gids met die titel "js" in die hooflys van die program.
Hierdie lêer, wat u in die "js" gids van die aansoek moet skep, sal verantwoordelik wees vir die wagwoord vir die vorms van inskrywing (formhash ()) en registrasie (regformhash ()):
funksie vormhash (vorm, wagwoord) {// Skep `n nuwe elementinskrywing, dit sal ons wagwoordveld met hash wees. var p = document.createElement ("insette") - // Voeg die nuwe element by ons vorm. form.appendChild (p) -p.name = "p"-p.type = "verborge"-p.value = hex_sha512 (password.value) - / Maak seker dat die gewone teks wagwoord nie gestuur is nie. password.value = ""- / / Laastens stuur die vorm. form.submit () -} funksie regformhash (vorm, uid, e-pos, wagwoord, conf) {// Kontroleer dat elke veld `n waarde het (uid.value == `` | | email.value == `` | . Waarde == `` || conf.value == ``) {alert (`Jy moet al die inligting verskaf wat versoek word, probeer asseblief weer`) - terugkeer vals -} // Gaan die usernamere = / ^ w + $ / - as (! re.test (form.username.value)) {alert ("Die gebruikersnaam moet slegs letters, getalle en onderstrepe bevat. Probeer asseblief weer") -form.username.focus () - return false -} // Maak seker dat die wagwoord het die korrekte uitbreiding (min 6 karakters) // verifikasie verdubbel hieronder, maar is ingesluit vir die gebruiker om `n // het. meer specific.if gids (password.value.length < 6) {waarskuwing ( `Die wagwoord moet ten minste 6 karakters Probeer asseblief weer ") -. Form.password.focus () - return false -} // Ten minste een nommer, `n klein en `n hoofletters // Ten minste 6 caracteresvar re = /(?=.*d)(?=.*[az])(?=.*[AZ]).{6,}/-if (! re.test (wagwoord .Value)) {waarskuwing ( `wagwoorde moet ten minste een nommer, een kleinletter en `n kapitale bevat probeer asseblief weer.`) - return false -} // Gaan die wagwoord en bevestiging is igualesif (wagwoord .value = conf.value) {waarskuwing ( `die wagwoord en bevestiging stem nie ooreen probeer asseblief weer.`) - form.password.focus () - return false -} // skep `n nuwe item inskrywing, Dit sal ons wagwoordveld met hash wees. var p = document.createElement ("insette") - // Voeg die nuwe element by ons vorm. form.appendChild (p) -p.name = "p"-p.type = "verborge"-p.value = hex_sha512 (password.value) - / Maak seker dat die gewone teks wagwoord nie gestuur is nie. password.value = ""-conf.value = ""- / / Laastens stuur die vorm. form.submit () - return true-}
In beide gevalle stel jаvascript `n hash op die wagwoord en dra dit oor na POST-data wanneer `n verborge veld geskep en gevul word.
Deel 7
Skep HTML-bladsye
Hierdie is `n vorm van HTML met twee teksvelde, getiteld "e-pos" en "wagwoord". Die vorm stuur knoppie sal die jаvascript-funksie "formhash ()", wat `n wagwoord hash genereer en stuur die inhoud van "e-pos" en "p" (hashed wagwoord) aan die bediener noem. U moet hierdie lêer in die hoofmap van die program skep.
By die aanvang van die sessie is dit die beste om iets te gebruik wat nie publiek is nie. In hierdie gids gebruik ons die e-pos as die aanmeld ID, maar die gebruikersnaam kan dan gebruik word om die gebruiker te identifiseer. As die e-pos versteek is in `n bladsy binne die breër program, sal `n ander onbekende veranderlike bygevoeg word om die rekeninge te kraak.
Let wel: alhoewel ons die wagwoord geïnkripteer sodat dit nie in plain text gestuur, is dit noodsaaklik dat jy die HTTPS-protokol (TLS / SSL) gebruik wanneer die stuur van wagwoorde om `n produksie stelsel. Dit is nie oorbodig om te dring dat net `n wagwoord onvoldoende sal wees nie. Jy kan `n "man-in-die-middel" aanval ly wat die gestuurde hash kan lees en gebruik om aan te meld.
Phpinclude_once `sluit / db_connect.php`-include_once` sluit / functions.php`-sec_session_start () - as (login_check ($ mysqli) == ware) {$ aangemeld = `in`-} anders {$ aangemeld =` uit `-}?>Veilige Login: Teken in phpif (isset ($ _ GET [`error`])) {echo `Fout by aanmelding!
`-}?>As jy nie `n rekening het nie, assebliefregistreer.
As dit verby is, assebliefmaak die sessie toe.
Dit is verbind. php echo $ aangemeld?>.
Skep `n nuwe PHP-webblad met die naam "register_success.php" in die hooflys van die program. Dit is die bladsy waar u na die gebruiker herlei sal word nadat u suksesvol geregistreer het. Uiteraard kan u hierdie bladsy maak soos u wil, of u kan dit na `n ander bladsy lei (of nie). Dit sal afhang van jou. U moet die bladsy in die hoofmap van die aansoek opspoor. Die huidige bladsy "register_success.php" wat ons geskryf het, lyk soos volg:
Veilige aanmelding: Suksesvolle registrasie Suksesvolle registrasie!
Nou kan jy teruggaan nadie login bladsy en begin die sessie.
Skep `n nuwe HTML-bladsy in die hoofmap van die program en noem dit "error.php". Dit is die bladsy waar u na die gebruiker herlei sal word in die geval van `n fout tydens die aanvang van die sessie, registrasie of wanneer u `n veilige sessie probeer vestig. Die onderstaande kode sal eenvoudig `n algemene foutbladsy wys. Miskien het jy iets `n bietjie meer gesofistikeerd nodig. Hou egter in gedagte dat alles wat by die bladsy gevoeg word, korrek gefilter moet word om te beskerm teen moontlike XSS aanvalle. Die voorbeeldkode van die bladsy is die volgende:
Php $ fout = filter_input (INPUT_GET, `dwaal`, $ filter = FILTER_SANITIZE_STRING) -As (! $ Fout) {$ fout = " `n Onbekende fout het voorgekom" -}?>Veilige aanmelding: Fout Daar was `n probleem.
php echo $ error-?>
Deel 8
Beskerm bladsye
Een van die mees algemene probleme met verifikasie stelsels is dat die ontwikkelaar vergeet om te verifieer of die gebruiker verbind is. Dit sal baie belangrik wees dat u die onderstaande kode op elke beskermde bladsy gebruik om seker te maak dat die gebruiker verbind is. Maak seker dat jy hierdie funksie gebruik.
// Voeg die verbinding en die funksies van die databasis hier. Sien 3.1. sec_session_start () - indien (login_check ($ mysqli) == waar) {// Voeg die inhoud van jou beskermde bladsy hier by! } else {echo "Jy is nie gemagtig om toegang tot hierdie bladsy te kry nie. Asseblief, begin jou sessie ".-}
As voorbeeld van wat jy moet doen, het ons `n voorbeeld beskermde bladsy ingesluit. Skep `n lêer met die naam "protected_page.php" in die hooflys van die program. Die lêer moet soortgelyk wees aan wat ons volgende sal wys:
phpinclude_once `includes / db_connect.php`-include_once` bevat / functions.php`-sec_session_start () -?>Veilige login: Beskermde bladsy php as (login_check ($ mysqli) == waar) :?>Welkom, php echo htmlentities ($ _ SESSION [`gebruikersnaam`]) -?>!
Dit is `n voorbeeld van `n beskermde bladsy. Om toegang tot hierdie bladsy te verkry, moet gebruikers inteken. Op `n sekere tyd sal ons ook die rol van die gebruiker verifieer sodat die bladsye die tipe gebruiker wat gemagtig is om toegang tot die bladsy te bepaal, kan bepaal.
Terug na dielogin bladsy.
php anders :?>Jy is nie gemagtig om toegang tot hierdie bladsy te kry nie. asseblief login.
php endif-?>
Ons aansoek sal die gebruiker na hierdie bladsy herlei nadat hy suksesvol geregistreer het. Dit is duidelik dat u implementering nie dieselfde moet wees nie.
wenke
- Kom weg van die md5-funksie in die aanmeldskrips, die md5-hash-algoritme word oorweeg onseker.
- Met baie min veranderinge in hierdie voorbeeld skrifte sal jy met ander SQL-stelsels, soos SQLite of PostgreSQL, kan werk.
- Gebruik HTML en CSS om die toegang en uittreevorm van die bladsye wat jy wil, te formateer.
- As jy `n ander hash-algoritme in plaas van sha512 wil gebruik, probeer Whirlpool. Vermy die gebruik van Gost, sha1 (tensy dit goed gesout is en verskeie iterasies het) en, soos ons reeds genoem het, md5. Moedig jou gebruikers aan om unieke, veilige wagwoorde te skep, met hoofletters, kleinletters, syfers en simbole. Oorweeg dit om jou gebruikers te vra om `n aanmeldnaam anders as hul gebruikersnaam te maak om dit veiliger te maak.
waarskuwings
- Die tuisblad en registrasie moet HTTPS gebruik. Die skrifte van hierdie artikel het jy nie dwing om dit te doen en, in werklikheid, sou dit makliker nie om dit te doen tydens die ontwikkeling wees, maar moet nie hierdie skrifte te gebruik in `n produksie-omgewing, tensy jy gebruik HTTPS.
- Maak seker dat die gebruiker nie jou PHP-skrifte kan sien nie, wat kan gebeur as gevolg van die foutiewe konfigurasie van die bediener. Daar is `n moontlikheid vir gebruikers om inligting oor jou databasis te versamel, soos name en wagwoorde as jou PHP-kode sigbaar is. Ideaal gesproke is alle skrifte wat in ander rye of bladsye ingesluit is, in `n gids buite die bediener se lêerstelsel geleë en word dit met `n relatiewe pad verwys, byvoorbeeld, voeg by: "../ .. /includes/myscript.inc.php ".
- Niks is 100% veilig nie. Onthou om tred te hou met die nuutste sekuriteitsnuus om die veiligheid van u skrifte te verbeter.
- Hierdie anti-brute kragskrif wat `n gebruiker se rekening blokkeer, kan baie maklik misbruik word. Ons beveel sterk aan om `n brute kragtegniek soos CAPTCHA te gebruik.
- Ons beveel aan om `n CAPTCHA op die aanmeldbladsy te gebruik om brute krag en DoS-aanvalle te voorkom. Die CAPTCHA moet op die vorm verskyn na twee onsuksesvolle aanmeldpogings, hoewel dit nog nie in die voorbeeldkode geïmplementeer is nie.
- U kan `n beter oplossing kry met `n raamwerk soos Zend 2, Symfony of CakePHP. Al hierdie raamwerke het reëlings vir veilige sessies en sekuriteitsmodules om te help met die aanmeldproses. As jy ook `n raamwerk gebruik, sal jy waarskynlik sien dat jy beter toepassings skryf.
- Hoe om jou Facebook-rekening te beveilig
- Hoe om die Xbox Live-diens te kanselleer
- Hoe om veilige programme vir die web te ontwikkel
- Hoe om veilige lêerverwijdering in CCleaner in te skakel
- Hoe om `n webwerf te hack
- Hoe kan jy inteken op Windows XP as administrateur
- Hoe om Wordpress in XAMPP te installeer
- Hoe om `n MySQL-bediener op `n rekenaar te installeer
- Hoe om SQL-navrae te stuur na die MySQL-opdraglyn
- Hoe om `n ontwikkelingsomgewing vir JSP te maak met Eclipse, Tomcat en MySQL
- Hoe om `n webblad te beskerm met `n wagwoord
- Hoe om jou gekapte hotmail rekening te herstel
- Hoe om PHP en MySQL te leer
- Hoe om die basiese beginsels van programmering te leer
- Hoe om programmering in C ++ te leer
- Hoe om jou webwerf te beveilig
- Hoe om te begin met programmering in C met Turbo C + + IDE
- Hoe om `n e-pos op Blackberry-toestelle op te stel
- Hoe om `n mobiele webwerf met Dreamweaver te skep
- Hoe om `n veilige sessiebestuurstelsel in PHP en MySQL te skep
- Hoe om `n dopkoekie te skep