NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Login a registr

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

Aktivity
Avatar
Martin Bubník:9.7.2017 19:08

Ahoj... Vytvářím základní registraci a přihlašování, registrace mi funguje, heslo zahashované atd.. Akorát mám problém s loginem.. Zde je zdrojový kód:

<?php
include "db.php";
session_start();

$username = htmlspecialchar­s($_POST["user­name"]);
$password = htmlspecialchar­s($_POST["pas­sword"]);
$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($sqlDo­taz);
$sqlProvedeni->execute(arra­y(":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($sqlDo­taz);
$sqlProvedeni->execute(arra­y(":username" => $username));
$pom = $sqlProvedeni->fetchALL();

//uložení záznamů
foreach ($pom as $value) {
$id = $value["id_user"];
$heslo = $value["passwor­d_user1"];
}
}
//vrácené hodnoty
if ($password == $heslo ) {
echo "seš přihlášen";
$_SESSION["id_u­ser"] = $id;
} else {
exit("Zadal jste špatně heslo nebo uživatelské jméno");

}
?>

Když zadám existující přihlašovací údaje, tak mi to vypíše tuto chybu:

Notice: Undefined variable: heslo in /var/www/html­/bubnima16/We­by/kniha/cvice­ni z knihy/action_lo­gin.php on line 38

Vím co ta chyba znamená, ale z jakého důvodu?? Pomůže mi prosím někdo??

 
Odpovědět
9.7.2017 19:08
Avatar
Odpovídá na Martin Bubník
Martin Konečný (pavelco1998):9.7.2017 19:40

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.

Nahoru Odpovědět
9.7.2017 19:40
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Martin Bubník:9.7.2017 21:30

Děkuji, a jak bych to měl napravit?

 
Nahoru Odpovědět
9.7.2017 21:30
Avatar
Odpovídá na Martin Bubník
Martin Konečný (pavelco1998):9.7.2017 21:36

Strčit tu další podmínku do toho bloku :D 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
        }
}
Nahoru Odpovědět
9.7.2017 21:36
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Martin Bubník:10.7.2017 9:31

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..

 
Nahoru Odpovědět
10.7.2017 9:31
Avatar
Jiří Fencl
Člen
Avatar
Jiří Fencl:10.7.2017 10:30

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_u­ser"] 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)

Editováno 10.7.2017 10:30
 
Nahoru Odpovědět
10.7.2017 10:30
Avatar
Odpovídá na Jiří Fencl
Martin Bubník:10.7.2017 10:35

Prostě to pořád píše Je špatně zadané heslo nebo... Víš co myslím..
A používám https:

 
Nahoru Odpovědět
10.7.2017 10:35
Avatar
Martin Bubník:10.7.2017 10:36

A hlavně.. Kamarád to má takhle a funguje mu to, a mě samozřejmě ne

 
Nahoru Odpovědět
10.7.2017 10:36
Avatar
Miskyns
Člen
Avatar
Odpovídá na Martin Bubník
Miskyns:10.7.2017 10:46

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...

Editováno 10.7.2017 10:47
Nahoru Odpovědět
10.7.2017 10:46
Proč se to učit, když můžeš použít GOOGLE...
Avatar
Odpovídá na Martin Bubník
Michal Haňáček:10.7.2017 10:47

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.

Editováno 10.7.2017 10:48
Nahoru Odpovědět
10.7.2017 10:47
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
Miskyns
Člen
Avatar
Odpovídá na Michal Haňáček
Miskyns:10.7.2017 10:48

Pokud se nepletu, tak asi chce zjístit zda řádek s danými parametry existuje :)

Nahoru Odpovědět
10.7.2017 10:48
Proč se to učit, když můžeš použít GOOGLE...
Avatar
Odpovídá na Miskyns
Michal Haňáček:10.7.2017 10:49

Což mu udělá i ten druhý dotaz :) ...

Nahoru Odpovědět
10.7.2017 10:49
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
Miskyns
Člen
Avatar
Odpovídá na Michal Haňáček
Miskyns:10.7.2017 10:49

Je pravda, že to mohl zkombinovat do toho posledního, a od toho se odrazit zda ten uživatel existuje :)

Nahoru Odpovědět
10.7.2017 10:49
Proč se to učit, když můžeš použít GOOGLE...
Avatar
Odpovídá na Miskyns
Michal Haňáček:10.7.2017 10:52

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.

Nahoru Odpovědět
10.7.2017 10:52
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
Miskyns
Člen
Avatar
Odpovídá na Michal Haňáček
Miskyns:10.7.2017 10:54

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 ;)

Editováno 10.7.2017 10:55
Nahoru Odpovědět
10.7.2017 10:54
Proč se to učit, když můžeš použít GOOGLE...
Avatar
Peter Trcka
Člen
Avatar
Peter Trcka:10.7.2017 10:57

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["passwor­d_user1"];
echo <br/>;
echo $password;

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
10.7.2017 10:57
Avatar
Odpovídá na Miskyns
Martin Bubník:10.7.2017 11:02

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");

        }


}
 
Nahoru Odpovědět
10.7.2017 11:02
Avatar
Miskyns
Člen
Avatar
Miskyns:10.7.2017 11:02

Normálně je ukládej, tak jak to bylo, ale bez toho foreach :)
To znamená

$id = $pom["id_user"];
$heslo = $pom["password_user1"];
Editováno 10.7.2017 11:04
Nahoru Odpovědět
10.7.2017 11:02
Proč se to učit, když můžeš použít GOOGLE...
Avatar
Odpovídá na Miskyns
Martin Bubník:10.7.2017 11:14

Notice: Undefined index: id_user in /var/www/html­/bubnima16/We­by/kniha/cvice­ni z knihy/action_lo­gin.php on line 32

Notice: Undefined index: password_user1 in /var/www/html­/bubnima16/We­by/kniha/cvice­ni z knihy/action_lo­gin.php on line 33
Zadal jste špatně heslo nebo uživatelské jméno

 
Nahoru Odpovědět
10.7.2017 11:14
Avatar
Miskyns
Člen
Avatar
Odpovídá na Martin Bubník
Miskyns:10.7.2017 11:30

Používáš PDO?

Nahoru Odpovědět
10.7.2017 11:30
Proč se to učit, když můžeš použít GOOGLE...
Avatar
Jiří Fencl
Člen
Avatar
Jiří Fencl:10.7.2017 12:20

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.

 
Nahoru Odpovědět
10.7.2017 12:20
Avatar
Martin Bubník:11.7.2017 20:34

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..";

}
?>
 
Nahoru Odpovědět
11.7.2017 20:34
Avatar
Odpovídá na Martin Bubník
Martin Konečný (pavelco1998):11.7.2017 23:23

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 ");
Nahoru Odpovědět
11.7.2017 23:23
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Martin Bubník:12.7.2017 8:48

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

 
Nahoru Odpovědět
12.7.2017 8:48
Avatar
Odpovídá na Martin Bubník
Martin Konečný (pavelco1998):12.7.2017 11:59

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.

Nahoru Odpovědět
12.7.2017 11:59
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 25 zpráv z 25.