Autor | Zpráva | ||
---|---|---|---|
blahapet Profil |
#1 · Zasláno: 17. 11. 2024, 14:39:38
Ahoj všem zkušeným, snažím se pochopit OOP a zkoušel jsem udělat jen tak letmo změnu v kódu při přihlašování do Administrace v eshopu.
Původní kód: if($_POST["send"] == "ok"): if($_POST["login"] == AUTHLOGIN and $_POST["pass"] == AUTHPASS): $_SESSION["login"] = $_POST["login"]; $_SESSION["pass"] = $_POST["pass"]; $_SESSION["msg"] = "<p class=\"msgr\">Vítejte v administraci.</p>"; header('Location: /admin/objednavky/'); exit(); else: $_SESSION["msg"] = "<p class=\"msgf\">Nesprávně zadané údaje</p>"; header('Location: /admin/'); exit(); endif; endif; Jsem to nahradil tímto: class PrihlaseniDoAdministrace { public $login; public $pass; public function __construct($login, $pass) { $this->login = $login; $this->pass = $pass; } public function logIn() { if($_POST["send"] == "ok"){ if($this->login == AUTHLOGIN and $this->pass == AUTHPASS){ $_SESSION["login"] = $this->login; $_SESSION["pass"] = $this->pass; $_SESSION["msg"] = "<p class=\"msgr\">Vítejte v administraci.</p>"; header('Location: /admin/objednavky/'); exit(); }else{ $_SESSION["msg"] = "<p class=\"msgf\">Nesprávně zadané údaje</p>"; header('Location: /admin/'); exit(); } } } } $PDA = new PrihlaseniDoAdministrace($_POST["login"], $_POST["pass"]); $PDA->logIn(); Takto mi přihlášení funguje, stejně jako s původním kódem. Jen se chci zeptat, jestli to je správný postup... Vím, že to tu je celkem omletá písnička, ale v podstatě v tom vidím jen práci navíc. Více řádků kódů než před tím. |
||
blahapet Profil |
#2 · Zasláno: 17. 11. 2024, 15:56:50
No, já už to asi začínám trochu chńápat... Měl jsem spoustu takových to dalších kódů krom toho na přihlášení. Další podmínka byla na automatické přihlášení do administrace v eshopu z odkazu v mailu:
/* ----------------------------------------- ADMINISTRACE - AUTOMATICKÉ PŘIHLÁŠENÍ ------------------------------------------- */ if($_REQUEST["raccess"] == md5(RACCESS)): $_SESSION["login"] = AUTHLOGIN; $_SESSION["pass"] = AUTHPASS; endif; Nebo pak na odhlášení: if($_REQUEST["logout"] == "ok"): $_SESSION["msg"] = "<p class=\"msgr\">Byl jste úspěšně odhlášen.</p>"; header('Location: /admin/'); exit(); endif; Tak jsem to dal vše do jedné třídy Administrace a navíc zprávu s přesměrováním taky do funkce. function SendMSG($msg, $location, $type) { $_SESSION["msg"] = "<p class=\"msg".($type == true ? "r" : "f")."\">".$msg."</p>"; header('Location: '.$location); exit(); } class Administrace { public $login; public $pass; public function __construct($login, $pass) { $this->login = $login; $this->pass = $pass; } public function logIn() { if($_POST["send"] == "ok"){ if($this->login == AUTHLOGIN and $this->pass == AUTHPASS){ $_SESSION["login"] = $this->login; $_SESSION["pass"] = $this->pass; SendMSG("Vítejte v administraci.", "/admin/objednavky/", true); }else{ SendMSG("Nesprávně zadané údaje!", "/admin/", false); } } } public function logOut() { if($_REQUEST["logout"] == "ok"){ unset($_SESSION["login"]); unset($_SESSION["pass"]); SendMSG("Byl jste úspěšně odhlášen.", "/admin/", true); } } public function AutoLogIn() { if($_REQUEST["raccess"] == md5(RACCESS)){ $_SESSION["login"] = AUTHLOGIN; $_SESSION["pass"] = AUTHPASS; } } } $admin = new Administrace($_POST["login"], $_POST["pass"]); $admin->logIn(); $admin->logOut(); $admin->AutoLogIn(); Takže chápu-li dobře, uceluje to a zpřehledňuje kód. Akorát ty další věci, jako k čemu je privátní proměná nebo fce, try, catch budu muset dál nastudovat :-) |
||
Rastíík Profil * |
#3 · Zasláno: 17. 11. 2024, 20:29:24
blahapet:
„Takže chápu-li dobře, uceluje to a zpřehledňuje kód.“ Ano, i to je jeden z benefitů. Nicméně to lze udělat i jednoduše přes funkce a soubory, nikoliv za použití tříd (OOP), jen tak mimochodem... Z mé zkušenosti je nejlepší na to nahlížet opravdu jako na část kódu, kterou lze pře-použít na několika místech zároveň a která si umí uchovávat nějaký vnitřní stav. Prostě s tím pracuj a postupem času ti to začne docházet, uvidíš souvislosti, výhody, a tak podobně. Nebudu ti tu psát, o čem OOP reálně je, na to si najdi tutoriály a nebo se zeptej ChatGPT. Nicméně máš dobrý start! Jen tak dál :) „Akorát ty další věci, jako k čemu je privátní proměnná nebo fce, try, catch budu muset dál nastudovat“ Privátní, popř. též protected, proměnné a funkce pak řeší přístup do vnitřností třídy z venčí (např. to tvoje $admin->logIn() ), ať už úplně mimo tu třídu a nebo třeba v případě dědičnosti pak řeší přístupy z potomků (to je to "protected", snad se nepletu). Pokud si píšeš svůj vlastní kód a nepoužíváš externí knihovny, asi se s tím zas tak běžně nesetkáš. Řekněme, že je to taková poučka či dokumentace pro ostatní programátory (včetně tvého budoucího já), kterým říkáš, že nechceš, aby nějaká proměnná/funkce byla přístupné zvenčí. Z jakéhokoliv důvodu... Spousta jazyků to pak nemá pouze jako dokumentaci (tedy nemá to jen informativní charakter pro ostatní), ale má to prostě a jednoduše nepřístupné. Chceš-li volat privátní metodu tam, kde nemáš, tak tě to prostě nepustí a skončí to chybou.
Ve tvém případě by třeba proměnná $pass mohla být privátní. Protože přeci nechceš tuto proměnnou využívat mimo tu třídu, nebo ano?
Try and catch je pak úplně něco jiného, nesouvisí to nijak s OOP. Je to konstrukt, kterým říkáš: Já předem očekávám, že tato část kódu může skončit nějakou konkrétní chybou (též výjimkou). Pokud tak doopravdy nastane, tak s tím počítám a chci udělat **něco**. Pokud ta konkrétní chyba však nenastane, to **něco** dělat nechci. Opět to tu nebudu popisovat více dopodrobna, můžeš si najít nějaký článek. „Další podmínka byla na automatické přihlášení do administrace v eshopu z odkazu v mailu“ Přečti si to znovu. Přijde ti to opravdu jako dobrý nápad? Proč se to asi běžně nepoužívá? Facebook, bankovnictví, alza, nikde nic takového určitě nejde. Proč asi? --- Tvůj kód obsahuje věci, které nejsou úplně dobře. Ale nechci ti to tu hejtit a předělávat. Ono na to postupem času narazíš sám. Prostě programuj, uč se, a ono se to časem bude zlepšovat, pokud tomu dáš tu píli... Nicméně pár bodů: - Ve funkci SendMSG vkládáš proměnnou $msg jen tak, bez jakékoliv ochrany. Teď to možná nevadí, ale garantuji ti, že za měsíc na to zapomeneš a rozhodneš se přivítat uživatele jeho jménem, např. zavoláš SendMSG("Vítejte v administraci, $user->username", "/", true) a ejhle, bezpečnostní problém. Mrkni se na funkci htmlspecialchars .
- Používáš podmínku if($_POST["send"] == "ok") . Co když v $_POST nic nebude, nebo tam nebude ten klíč send ? Ajajaj... Podívej se na empty a isset (nebo alespoň tyhle věci se používali ještě v PHP5, kde jsem programoval kdysi já; ujisti se, že používáš aktuální způsoby kontroly)
- Ty si ukládáš $_SESSION["pass"] = $this->pass; . Proč? Na co? Myslíš si, že je to dobře?
- Funkce md5 už není úplně bezpečná. Doporučuji si o tom něco prostudovat a použít něco jiného. PHP kdysi mělo funkci password_verify a k ní přidruženou hashovací funkci.
- Mixuješ češtinu a angličtinu. Přijde ti to přehledné? Píšeš, že je to administrace eshopu. Pokud programuješ eshop, aby ses naučil programovat, skvělé, jen tak dál. Pokud tohle opravdu někdo používá pro svůj byznys a lidi přes to mají něco objednávat a zadávat tam svoje osobní údaje, mám docela strach... |
||
blahapet Profil |
#4 · Zasláno: 18. 11. 2024, 05:35:13
Díky moc za názory i za kritiku... Snažím se to tak nějak vyvíjet jako samouk a rád si nechám poradit.
Co se týče té administrace a automatického přihlašování: administrace v tomto případě je myšleno jako správce eshopu ne uživatele (nákupčího). Fci htmlspecialchars() stejně jako mysqli_real_escape_string() jinak běžně používám, ale nehodlám v tomto případě někoho vítat. Jinak chápu problematiku samozřejmě. To automatické přihlašování mělo být tak, že při dokončení objednávky přijde notifikační mail administrátorovi o nové objednávce a on jedním klikem na odkaz v mailu se dostane na detail objednávky, kde se v tu danou chvíli i zároveň přihlásí. Řešil jsem to odkazem takto: /admin/objednavky/20241117/raccess/6fa52dbfe2e6d7e151e16e529af2df0f/ Kde hodnota "raccess" jsou pomocí md5() zaheslované přihlašovací údaje administrátora. Ty pak ověřuji u detailu objednávky a pokud se shodují, zobrazím objednávku. Zřejmě to asi nebude ten nejbezpečnější způsob, rád si nechám poradit. Ohledně isset() a empty() také děkuji. |
||
anonym_ Profil * |
#5 · Zasláno: 18. 11. 2024, 08:02:44
blahapet:
„Zřejmě to asi nebude ten nejbezpečnější způsob, rád si nechám poradit.“ Není vůbec bezpečný. Pro tvůj malý e-shop o pár objednávkách si to tam klidně nech, ale ať tě proboha nenapadne něco takového prodávat klientům. |
||
blahapet Profil |
Dvě otázky:
1) Jak toho lze zneužít? 2) Bezpečnější způsob. Moc děkuji. |
||
anonym_ Profil * |
blahapet:
Mícháš několik věcí dohromady 1. učit se programovat (od základu) 2. řešit bezpečnost aplikace Přihlásit se kamkoliv bez nutnosti zadat přihlašovací údaje bezpečně nejde. A založit to na "tajné" URL vzniklé jakkoliv, natožpak MD5 hashem, který prolomíš v řádu sekund, je prostě nesmysl. Permanentní login lze řešit skrz cookies, a řeší se tak snad už 20 let. Pokud je cookina aktivní, po zadání URL do administrace může dojít k loginu. Pokud ne, redirect na přihlášení. Na tvém místě bych se naučil základy jazyka. Bez vazby na konkrétní aplikaci, prostě se učit. Číst, studovat, psát, zkoušet. Pak začít studovat něco o bezpečnosti aplikací. A teprve pak se pouštět do něčeho komplexnějšího, jako je eshop. To sousto je dost velké a v momentě, kdy se rozhodneš to někomu prodat, dost nebezpečné. |
||
blahapet Profil |
#8 · Zasláno: 18. 11. 2024, 09:13:36
Ok, díky moc.
|
||
Rastíík Profil * |
#9 · Zasláno: 18. 11. 2024, 11:42:26
blahapet:
„1) Jak toho lze zneužít?“ Jak již bylo řečeno, MD5 už jde rozlousknout během vteřin... Navíc, ten hash zůstává stále stejný! Takže pokud ho někdo jakkoliv získá (odposlechne email, podívá se ti do historie prohlížeče, cokoliv), bude mít už navždy přístup do administrace a to úplně bez práce... A vlastně ani nemusí rozlouskávat hash. Vždyť on samotný tě taky přihlásí... „2) Bezpečnější způsob.“ Jak již bylo také řečeno, cookies. Můžeš si do nich něco uložit a ono to v nich furt bude, když se uživatel vrátí druhý den a mezi tím vypne počítač... Doporučuji si o tom nejprve něco nastudovat a pak mrknout opět na nějaké tutoriály. Nyní jsem v rychlosti hledal a musím říct, že moc dobrých jsem jich nenašel, tento však docela ušel... Je důležité si uvědomit, že cookies si může uživatel v zásadě změnit, takže uložit si do cookies třeba ID uživatele, a nebo jen nějakou informaci ne/přihlášen , je chyba. Vždy by sis tam měl uložit i něco dalšího, nějaký hash, který pak s něčím zkontroluješ. Ideálně by se ten hash měl měnit během každého přihlášení, a tak podobně...
Jinak tedy naprostou souhlasím s anonym_em. Máš se ještě dost co učit. Klidně si dělej eshop, jen prosím, ať ho nikdo nepoužívá... :D Já třeba začínal tak, že jsem si psal mini aplikace pro sebe. Např. stránku, kam jsem si psal nějaké úkoly, pak poznámky, kalendářík... Nebo aplikaci, kam jsem si dával známky ze školy a ono mi to i počítalo průměry. Pak jsem si třeba udělal script, který mi odněkud zjistil předpověď počasí, nejnovější zprávy a poslal mi to na email. Všechno to byly mnooohem jednodušší věci, než je eshop, a o to jednodušší bylo i se něco přiučit. |
||
blahapet Profil |
#10 · Zasláno: 18. 11. 2024, 11:54:35
Ok, díky moc ještě jednou.
|
||
N71 Profil * |
#11 · Zasláno: 19. 11. 2024, 13:36:31
Obecně nestačí přepsat špagetový kód do objektového a říkat tomu OOP. Objektové programy mají odlišnou logiku a strukturu, jsou míň sekvenční a víc hierarchické.
Nastuduj si základy OOP nejen z hlediska syntaxe, ale hlavně z hlediska návrhových vzorů. A/Nebo začni používat framework, který takové principy striktně dodržuje (Symfony, Laravel, Nette). |
||
Časová prodleva: 11 měsíců
|
0