Diskuze: Změna hesla v PHP
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 28 zpráv z 28.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
U řádku na kterém je
Db::query('SELECT id FROM uzivatele WHERE jmeno=?')
nedosazuješ za otazník hodnotu.
Podle mě je tam chyb hned několik:
1:
Db::query('SELECT id FROM uzivatele WHERE jmeno=?') // Chybí parametr, který se dosadí za otazník
Db::query('SELECT id FROM uzivatele WHERE jmeno=?', [$jmeno]) // Takto by mohla vypadat oprava
2:
$_POST['nove_heslo'] = $_POST['nove_heslo_znovu'] // Pokud se ptáš na shodu, je nutné použít dvě nebo tři rovnítka
$_POST['nove_heslo'] === $_POST['nove_heslo_znovu'] // Takto by mohla vypadat oprava
3:
Db::query('
UPDATE SHA1(heslo)
FROM uzivatele
WHERE id=?
', $_POST['nove_heslo'] . "123456789"); // Nejsem si jist, ale myslím, že ve wrapperu z této sítě je nutno dávat parametry do pole
Db::query('
UPDATE SHA1(heslo)
FROM uzivatele
WHERE id=?
', [$_POST['nove_heslo'] . "123456789"]); // Takto by mohla vypadat oprava
if ($_POST['stare_heslo'] = Db::query('SELECT id FROM uzivatele WHERE jmeno=?')
ještě kontroluješ jestli se staré heslo rovná id uživatele
To je podlě mě blbost, staré heslo se nemůže rovnat id, protože pak by to bylo třeba 123456 = 1. Ne ?
jo, ale takhle to tam máš ty
když s tím v podstatě začínáš, tak to dělej pomalu a sleduj, jaká
metoda má jaké návratové hodnoty. Sice neznám místní DB wrapper, ale je
mi jasný, že metoda Db::query() ti nebude vracet jeden konkrétní výsledek
jednoho sloupce.
Ty potřebuješ zjistit, jestli se staré heslo shoduje s tím v databázi. K
tomu máš dvě možnosti:
A mimo to, rovnítko v PHP můžeš použít na tři způsoby
$a = 10; // přiřazení hodnoty, tady bude výsledek vždycky TRUE! tohle když použiješ v podmínce, tak ti vždycky projde
$a == 10; // porovná proměnnou s číslem 10, při tom nezáleží na datovém typu ($a může být 10 jako číslo i 10 jako řetězec)
$a === 10; // porovná proměnnou s číslem deset a zároven udělá shodu datových typů. Pokud $a bude řetězec ($a = "10"), tak výsledek bude FALSE
($a = FALSE) == FALSE
// ALE
($a = TRUE) == TRUE
// !!!
zajímavé, beru zpět. Nicméně házet do podmínky jedno rovnítko je sebevražda sama o sobě
takže jak by podle tebe měl vypadat kód ?
Neznám ten DB wrapper, ale asi něco takovýho
$vysledek = DB::query("
SELECT heslo
FROM uzivatel
WHERE id = ?
", array($_SESSION["uzivatel_id"]));
$data = $vysledek->fetch();
$stareHeslo = nejakaHashFunkce($_POST["stare_heslo"]);
if ($stareHeslo === $data["heslo"]) {
// OK
}
A to jsem myslel, že to vrací výsledek "operace". Nicméně se to do
podmínky přetypuje na bool, což ve většině případů znamená TRUE a
začátečník na tom hezky narazí, pokud nebude přesně vědět, co dělá
Každopádně díky za upozornění
To je hezký, ale takhle ti nemá kdo jak poradit. Co zkusit třeba napsat, proč to nefunguje (chybové hlášení, co to má dělat a co to dělá, ...)? Jinak jsem psal, že ten DB wrapper neznám, jen jsem ti nastínil, jak by to mohlo vypadat.
Já si ještě našel na w3shools.com postupy, jakými to dělat bez tohoto wrapperu.
díky za informaci Pokud
používáš PDO, je to OK. Já používám primárně Doctrine 2, případně
Nette\Database (pokud fakt musim a neni jiná možnost), s ničím jiným
zkušenosti nemám
No já používám zatím jen mysqli, ale k PDO se taky dostanu. Jinak teď používám databáze na Virt. PC s Linuxem.
mysqli je skoro to samý co PDO. Doporučuji PDO
Princip je asi takový, že při předání hodnot z formuláře se ověří
shodnost otisku zadaného starého hesla s otiskem uloženým v databázi u
konkrétního uživatele (přihlášeného) a shodnost obou zadání nového
hesla. Pokud podmínka projde dojde k aktualizaci uloženého otisku hesla v
databázi otiskem nového hesla.
Kód si musíš přizpůsobit svým potřebám, nastavením a dalším
věcem.
if ($_POST)
{
if (sha1($_POST['stare_heslo']) == Db::query('SELECT heslo FROM uzivatele WHERE id=?', $_SESSION['uzivatel_id'] && $_POST['nove_heslo'] == $_POST['nove_heslo_znovu'])
{
Db::query('
UPDATE uzivatele
SET heslo=sha1(?)
WHERE id=?
', $_POST['nove_heslo'], $_SESSION['uzivatel_id']);
echo('<p style="text-align: center; font-size: 25px;">Heslo bylo úspěšně změněno.</p>');
}
else
echo('<p style="text-align: center; font-size: 25px;">Heslo se nepodařilo změnit, zkuste to znovu.</p>');
}
Jenom takové dvě menší poznámky.
No, já zatím neumím odesílat maily s těmahle informace. Tak se tě rovnou ptám, jak na to a taky bych potřeboval vědět, jak v emailu odřádkovat nový řádek.
1. vycházel sem z původního kódu tazatele, abych mu nastínil způsob jakým má nad tím uvažovat, nicméně:
if ($_POST)
{
if (sha1($_POST['stare_heslo']) == Db::query('SELECT heslo FROM uzivatele WHERE id=?', $_SESSION['uzivatel_id'])
{
if($_POST['nove_heslo'] == $_POST['nove_heslo_znovu'])
{
Db::query('UPDATE uzivatele SET heslo = sha1(?) WHERE id = ?', $_POST['nove_heslo'], $_SESSION['uzivatel_id']);
$zprava = 'Heslo bylo úspěšně změněno.';
}
else{$zprava = 'Zadání nového hesla se neshodují.';}
}
else {$zprava = 'Špatně zadané původní heslo.';}
}
if (isset($zprava)){echo('<p>' . $zprava . '</p>');}
2. vycházím opět z původního kódu v tutorialu, nějak víc sem nezkoumal ani wrapper ani nic dalšího. Případná oprava je už jen drobnost.
Maily obsahující heslo ani neposílej.
Odřádkování v mailu provedeš podle toho v jakém typu (dáno hlavičkou
content-type) to odesíláš.
Pokud posíláš jako prostý text (content-type: text/plain) tak odřádkuješ
pomocí
\n
, pokud to posíláš jako formátovaný html (content-type: text/html) tak musíš používat tag
<br>
No jo, ale jak to heslo potom říct tomu uživateli ?
Ten uživatel to heslo napíše. Tak nějak se předpokládá, že uživatel ví, co za heslo napsal.
Zobrazeno 28 zpráv z 28.