Diskuze: Login a registr
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 25 zpráv z 25.
//= 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.
Ahoj,
uzavírej to příště prosím do kódu, ať je to přehledné.
Problém je asi v tom, pokud správně vidím, že proměnnou $heslo definuješ v bloku if ($rows["0"] == 1), ale používáš ji mimo ten blok. Tzn. pokud ta podmínka neprojde, pak ta proměnná neexistuje, a tudíž ti to hlásí tu chybu.
Děkuji, a jak bych to měl napravit?
Strčit tu další podmínku do toho bloku Pokud neexistuje uživatel s daným jménem, není důvod kontrolovat heslo (vlastně ani není s čím jej srovnávat). Tudíž něco takového
if ($rows["0"] == 1) {
if ($password === $heslo) {
// ok
}
}
Děkuji.. Už to nehlásí chybu. Ale stále se mi nedaří přihlásit přes zaregistrovaného uživatele:
<?php
include "db.php";
session_start();
$username = htmlspecialchars($_POST["username"]);
$password = htmlspecialchars($_POST["password"]);
$password = hash("sha256", $password);
if (empty($username) || empty($password)) {
exit("Musíte vyplnit přihlašovací údaje");
//inputy
}
// počet záznamů
$sqlDotaz = "SELECT count(*) FROM users WHERE username_user = :username"; //počet záznamů
$sqlProvedeni = $db->prepare($sqlDotaz);
$sqlProvedeni->execute(array(":username" => $username));
$rows = $sqlProvedeni->fetch();
//kontrola zda li je záznam
if ($rows["0"] == 1) {
$sqlDotaz = "SELECT id_user, password_user1 FROM users WHERE username_user = :username"; //počet záznamů
$sqlProvedeni = $db->prepare($sqlDotaz);
$sqlProvedeni->execute(array(":username" => $username));
$pom = $sqlProvedeni->fetchALL();
//uložení záznamů
foreach ($pom as $value) {
$id = $value["id_user"];
$heslo = $value["password_user1"];
}
if ($password === $heslo ) {
echo "seš přihlášen";
$_SESSION["id_user"] = $id;
} else {
exit("Zadal jste špatně heslo nebo uživatelské jméno");
}
}
?>
Screen shot tabulky v databázi je zde přiložen.. Nevím kde je chyba, už nad tím nějakou chvíli dumám..
Ahoj, musis trosku upresnit to
stále se mi nedaří přihlásit
Mozna to zrovna neni ono, ale treba mi tam chybi uplne na zacatku po session_start nejaky test hodnoty $_SESSION["id_user"] aby se dokola neprihlasoval uz prihlaseny user.
Pokud se ti nedari dostat k tomu "ses prihlasen", tak budes muset postupne logovat hodnoty pro podminky, co tam vedou.
Taky kdyz uz pouzivas tento zpusob overovani hesla a username zvlast, tak si tam pridej SALT - takhle ti netem beha heslo v surove podobe (nepredpokladam, ze pouzivas HTTPs)
Prostě to pořád píše Je špatně zadané heslo nebo... Víš co
myslím..
A používám https:
A hlavně.. Kamarád to má takhle a funguje mu to, a mě samozřejmě ne
Nějak se mi nezdá tohle
//uložení záznamů
foreach ($pom as $value) {
$id = $value["id_user"];
$heslo = $value["password_user1"];
}
Následující poznatky (mohou být)
1. Máš tam heslo jako nesmyslný blábol (viz...
Mates454)
Pozn : Pokud se na něj nepokoušíš přihlásit, je to v
pořádku...
3. Nezdá se mi ten foreach (zkus odstranit foreach, a
přiřadit hodnoty rovnou)
Pozn : Nemusí být řešení, ale mohl by jsi to zkusit...
Co má dělat tohle ?
if ($rows["0"] == 1) { ... }
Není to trochy zbytečný? Jednak posíláš 2 dotazy do DB a jednak ti to zbytečně komplikuje ten kód ... myslím.
Pokud se nepletu, tak asi chce zjístit zda řádek s danými parametry existuje
Je pravda, že to mohl zkombinovat do toho posledního, a od toho se odrazit zda ten uživatel existuje
Asi bych hledal rovnou konkrétního uživatele s daným jménem a heslem. Pokud najde, tak ok. Přiřadit do session, pokud ne, tak hláška ven ... minimalizuje tím zátěž DB (zbytečný dotazy) a vyhodí ten zbytečnej foreach ...
Můj názor.
I když při takovém malém kódu, který získává pár údaju je ten pokles výkonu zanedbatelný, ale při větších aplikacích to může být horší Ale lepší to optimalizovat teď než potom
Ahoj,
v prvom rade by som si ten na tvojom mieste značne osekal. čím viac kódu, tým vačšia šanca, že dôjde niekde k chybe a tiež sa ti to celú aplikáciu spomaluje.
časť:
// počet záznamů
$sqlDotaz = "SELECT count(*) FROM users WHERE username_user = :username"; //počet záznamů
$sqlProvedeni = $db->prepare($sqlDotaz);
$sqlProvedeni->execute(array(":username" => $username));
$rows = $sqlProvedeni->fetch();
je zbytočná, pretože username by malo byt v databaze s vlastnostou unique (nemôžeš mať viac užívateľov s rovnakým username). Sql funkcia count(*) ti môže preto vátit buď 0 - užívateľ nie je v DB-tabulke alebo 1 - užívateľ v DB už je. Ak máš veľa záznamov a užívateľ už mysql našiel script bude pokračovať ďalej až kým neprejde celú tabuľku (on nevie, že tam je maximálne len jeden užívateľ).
preto ten kód úplne vynechaj a uprav to takto:
$sqlDotaz = "SELECT id_user, password_user1 FROM users WHERE username_user = :username LIMIT 1"; //počet záznamů
$sqlProvedeni = $db->prepare($sqlDotaz);
$sqlProvedeni->execute(array(":username" => $username));
$result = $sqlProvedeni->fetch(PDO::FETCH_ASSOC);
// ak sme nasli zaznam a sedi meno, heslo
if ($result>rowCount() == 1) {
//uložení záznamů
$id = $record["id_user"];
$heslo = $record["password_user1"];
if ($password === $heslo ) {
echo "seš přihlášen";
$_SESSION["id_user"] = $id;
} else {
exit("Zadal jste špatně heslo nebo uživatelské jméno");
}
}
dôvod prečo ťa neprihlási môže byť:
máš napríklad krátky rozsah stĺpca v DTB
prvé dva záznamy nemajú zahashované heslo
skús si vypísať
echo $record["password_user1"];
echo <br/>;
echo $password;
Odstranil jsem Foreach, ale jak mám udat ty hodnoty rovnou?? :
if ($rows["0"] == 1) {
$sqlDotaz = "SELECT id_user, password_user1 FROM users WHERE username_user = :username"; //počet záznamů
$sqlProvedeni = $db->prepare($sqlDotaz);
$sqlProvedeni->execute(array(":username" => $username));
$pom = $sqlProvedeni->fetchALL();
$id = "id_user";
$heslo = "password_user1";
if ($password == $heslo ) {
echo "seš přihlášen";
$_SESSION["id_user"] = $id;
} else {
exit("Zadal jste špatně heslo nebo uživatelské jméno");
}
}
Notice: Undefined index: id_user in /var/www/html/bubnima16/Weby/kniha/cviceni z knihy/action_login.php on line 32
Notice: Undefined index: password_user1 in
/var/www/html/bubnima16/Weby/kniha/cviceni z knihy/action_login.php on
line 33
Zadal jste špatně heslo nebo uživatelské jméno
fetchALL vraci pole a v polozce jsou teprve data, tak musis
$id = $pom[0]["id_user"];
Pak mam poznamku k navrhovanemu slouceni overeni jmena i hesla do jedne query : az dojde na bezpecnost bude potreba napr. SALT, tak se bude hodit, ze uz to je oddelene, takze bych to nechal.
A měl bych ještě jeden problém.. Mám ten registr, kontroluji jestli jsou zadané kolonky jako je jméno atd.. Kontroluje to všechno.. Kromě hesla, do teď mi to fungovalo, akorát jsem tam přidal datum narození a už to nefakčí.. Poradí prosím někdo??
<?php
session_start();
include "../db.php";
$username = htmlspecialchars($_POST["username"]);
$name = htmlspecialchars($_POST["name"]);
$lastname = htmlspecialchars($_POST["lastname"]);
$email = $_POST["email"];
$password = $_POST["password"];
$password = hash("sha256", $password);
$password_check = $_POST["password_check"];
$password_check = hash("sha256", $password_check);
$gender = $_POST["gender"];
$birth = $_POST["birth"];
// podmínky pro USERNAME
if (empty($username) || strstr(" ", $username)) {
exit("Musíte vyplnit uživatelské jméno..");
}
if (strlen($username) <= 2) {
exit("Uživatelské jméno musí obsahovat více jak 2 znaky..");
}
// podmínky pro NAME
if (empty($name) || strstr(" ", $name)) {
exit("Musíte zadat své jméno..");
}
if (strlen($name) <= 2) {
exit("Jméno musí obsahovat více jak 2 znaky..");
}
// podmínky pro LASTNAME
if (empty($lastname) || strstr(" ", $lastname)) {
exit("Musíte zadat své příjmení..");
}
if (strlen($lastname) <= 2) {
exit("Příjmení jméno musí obsahovat více jak 2 znaky..");
}
// podmínky pro EMAIL
if (empty($email) || strstr(" ", $email)) {
exit("Musíte zadat váš email..");
}
if (strstr("@", $email) || strstr(".cz", $email) || strstr(".com", $email) || strstr(".sk", $email)) {
exit("Musíte správně zadat svůj email..");
}
// podmínky pro PASSWORD
if (empty($password) || strstr(" ", $password)) {
exit("Musíte zadat své heslo..");
}
if (strlen($password) < 5) {
exit("Heslo musí obsahovat více jak 5 znaků..");
}
if ($password_check != $password) {
exit("Hesla se neshodují..");
}
//podmínky pro BIRTH
if (empty($birth) || strstr(" ", $birth)) {
exit("Musíte zadat své datum narození");
}
// podmínky pro INSERT
if ($_POST["username"] && $_POST["name"] && $_POST["lastname"] && $_POST["email"] && $_POST["password"] == $_POST["password_check"] && $_POST["gender"] && $_POST["birth"]) {
$sqldotaz = "INSERT INTO basket_users (username_user ,name_user, lastname_user, email_user, password_user, gender_user, birth_user) VALUES (:username, :name, :lastname, :email, :password, :gender, :birth)";
$sqlProvedeni = $db->prepare($sqldotaz);
$sqlProvedeni->execute(array(":name" => $name, ":lastname" => $lastname, ":email" => $email, ":password" => $password, ":username" => $username, ":gender" => $gender, ":birth" => $birth));
echo "Byl jste úspěšně zaregistrován.. Na svůj email dostanete potvrzení o registraci..";
}
?>
Ahoj,
co znamená, že to nefunguje?
Jinak když máš ošetřené chybové stavy předtím, nemusíš úplně na
konci mít tu dlouhou podmínku (podmínky pro INSERT).
Ještě doplním, že funkci htmlSpecialChars() je vhodnější používat až
na výstupu, ne na vstupu. Do databáze je obvykle vhodnější dávat data ve
stavu, v jakém přijdou (max. třeba odstranit mezery).
A taky bych pro jistotu nepoužíval prvky z pole $_POST, pokud jsi nejsi
jistý, že tam budou. Tzn. když ti někdo třeba nevyplní pole jména, tak
$_POST["username"] nemusí existovat.
Stačí to ošetřit jednoduše třeba
$username = isset($_POST["username"]) ? $_POST["username"] : NULL;
Pokud nepoužíváš nějaký framework, můžeš si ten zdlouhavý zápis zjednodušit např.
function getPost($key, $default = NULL)
{
if (isset($_POST[$key])) {
return $_POST[$key];
}
return $default;
}
// pak snadno použiješ
$username = getPost("username");
$password = getPost("password ");
$email = getPost("email ");
Znamená to, že tam mám kontroly na všechny inputy jak vidíš, když ten formulář zkouším.. Nevyplním například jméno, tak mě to upozorní že musím zadat jméno.. Ale jediný kde mi to nedělá je password
To bude asi tím, že když to heslo zahashuješ, tak nějaký obsah má, takže ti to nenapíše, že to nic neobsahuje. Musíš prvně zkontrolovat, zda ti něco z toho inputu přišlo a teprve pak hashovat.
Zobrazeno 25 zpráv z 25.