Skocz do zawartości

PDO prepare działa jakby miał lowercase


Rekomendowane odpowiedzi

Mam taki skrypcik:

$sql_query = "SELECT `login` FROM `users` WHERE LOWER(`login`) = :login AND `password` = :password";
$mysql_pdo_object = mysql_do_connect();
$stmt = $mysql_pdo_object->prepare($sql_query);
$stmt->execute(array('login' => $_POST['login'], 'password' => $_POST['password']));
echo $_POST['password'];
$count = $stmt ->rowCount();

if($count == 1)
{    	
echo 'Zalogowano!';
}else{
echo 'Nieprawidłowy login bądź hasło.';
}

Połączenie z bazą zawiera:

$pdoOptions = array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
    PDO::ATTR_CASE => PDO::CASE_NATURAL
);
try{		
	$pdo = new PDO(
	    "mysql:host=" . MYSQL_HOST . ";dbname=" . MYSQL_DATABASE, //DSN
	    MYSQL_USER, //Username
	    MYSQL_PASSWORD, //Password
	    $pdoOptions //Options	    
	);
	$pdo->exec("set names utf8");
}
catch(PDOException $ex){
	echo "Błąd.";
    die(json_encode(array('outcome' => false, 'message' => 'Unable to connect')));
}

Wszystko działa tylko jest jeden defekt. Mimo PDO::ATTR_CASE => PDO::CASE_NATURAL, skrypt wyświetla mi komunikat, że logowanie się powiodło nie zależnie czy porównuję np. "password", czy "PasSword", a przecież wielkie i małe litery mają klucze znaczenie w haśle. Chciałem potraktować na koniec sam login lowerem, a password pozostawić bez. Ale nie wiem z jakiego powodu wielkość liter i tak nie ma znacznie, a powinno.

 

Dodam, że to post password dodałem dla testu i echo ładnie pokazuje wielkie i małe litery w haśle. Więc w czym problem?


Spróbowałem nawet podwoić polecenie(na dwa sposoby i nic):

try{		
	$pdo = new PDO(
	    "mysql:host=" . MYSQL_HOST . ";dbname=" . MYSQL_DATABASE, //DSN
	    MYSQL_USER, //Username
	    MYSQL_PASSWORD, //Password
	    $pdoOptions //Options	    
	);	
	$pdo->setAttribute( PDO::ATTR_CASE, PDO::CASE_NATURAL );
	$pdo->exec("set names utf8");
}

 

Odnośnik do komentarza
Udostępnij na innych stronach

No ok. First things first. Nie przechowuje się haseł. Wtedy nie ma się problemu a wielkimi i małymi literami. Jeżeli ktoś dobierze się do twojej bazy danych to mogą cię czekać nawet srogie kary pieniężne.
Przechowuje się hash połączony z seed
https://www.php.net/manual/en/function.password-hash.php https://www.php.net/manual/en/function.password-verify.php

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

To, czy duże i małe znaki są odróżniane czy nie nie zależy od ustawień PDO, a od ustawienia kodowania danego pola w tabeli mysql. Spróbuj zmienić np. na utf8_bin .

 

A co do haseł jw. mamy co najmniej kilka ustaw które zabraniają trzymania ich w plaintekście. Nawet bez wycieku danych trzymanie czyjegoś hasła jawnie w swojej bazie jest równe ze zhackowaniem tej osoby - bo tak naprawdę masz loggera haseł wtedy.

Odnośnik do komentarza
Udostępnij na innych stronach

A niech mnie pozywają ile chcą ? Nie ma co się wszystkiego bać, bo człowiek niczego by nie zrobił. I tak nikt nie ma pojęcia czy mam dostęp do jego hasła czy nie. Później zamierzam dodać hashowanie, ale na razie nie ma na to czasu. Natomiast doceniam próbę uświadomienia mnie, bo zawsze warto się czegoś dowiedzieć, ale tutaj chodzi o to, że w ostatecznej wersji strony chcę dodać hashowanie. A takie pytanie jeszcze jak już o tym rozmawiamy. Jeśli używam hasha to jakiego typu pole musi być w MySQL? I jak przekazywać poprawnie dane przez PDO?

Co do tematu... Problem w tym, że z tabelką jest wszystko okej. Mogę do niej bez problemu zapisać wielkie i małe litery. Ale jak je rozróżnić? Kodowanie tabeli to UTF8_polish_ci

 

Wpisanie ręcznie komendy Select do PMA też nie rozróżnia wielkości liter. 


@e: a nawet posłucham mądrzejszych i zrobię hashowanie od razu :D Dzięki Threef za linki! Tylko jakie ustawienia tabeli zrobić? Pod jaki typ zmiennych?

@e: password_verify ( string $password , string $hash )  - jako argument dwa muszę podać hasło shashowane, tak?

Odnośnik do komentarza
Udostępnij na innych stronach

Jako argument podajesz chyba to co podał user z tym co masz dla danego loginu w bazie.

I podałem te funkcje jako przykłady. To nie są jedyne rozwiazania hashowania haseł. Ale są przynajmniej opisane

Odnośnik do komentarza
Udostępnij na innych stronach

40 minut temu, Threef napisał:

Jako argument podajesz chyba to co podał user z tym co masz dla danego loginu w bazie.

I podałem te funkcje jako przykłady. To nie są jedyne rozwiazania hashowania haseł. Ale są przynajmniej opisane

$password to dane wejściowe od usera, a $hash to wyciąg z bazy danych? I jaki typ pola w tabelce muszę zastosować? Text do 255 znaków?

Odnośnik do komentarza
Udostępnij na innych stronach

A czytałeś co zwraca funkcja?
 

 

Cytuj

 

The above example will output something similar to:


$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

 

Najlepiej jakbyś wygenerował kilka testowych i porównał co ci potrzeba. Ja nie wiem nie dotykałem SQL od 3 lat
Odnośnik do komentarza
Udostępnij na innych stronach

49 minut temu, Threef napisał:

A czytałeś co zwraca funkcja?
 

 


Najlepiej jakbyś wygenerował kilka testowych i porównał co ci potrzeba. Ja nie wiem nie dotykałem SQL od 3 lat

Zrobiłem prosty skrypcik do sprawdzenia wątpliwości i już wszystko wiem. Dzięki wszystkim za pomoc. Dzięki @Threef, dzięki @gnysek!


@e: jednak pojawił się inny problem jeszcze... Teraz trzeba robić dodatkową operację w phpie sprwadzania shashowanych haseł. Czy da się porównywać hasła shashowane na etapie jeszcze mysql?

Odnośnik do komentarza
Udostępnij na innych stronach

Nie lepiej do takich prostych zapytań skorzystać z jakiegoś ORMa, Doctrine? :D Wygodniej, szybciej i kod ładniej wygląda :) 

 

Luźny offtop - jak mnie GM zepsuł przy trzymaniu jakichkolwiek standardów tak teraz strasznie przyglądam się jak kod wygląda, a ten podany nie wygląda xD

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności
Dnia 18.12.2019 o 09:40, Threef napisał:

Tak. Generujesz hash a podanego hasła i wysyłasz go z zapytaniem by porównać

no co Ty, nowo wygenerowany hash będzie zawsze wyglądał inaczej niż ten już istniejący w bazie - dlatego porównuje się plaina z hashem przez password_verify
 

Dnia 17.12.2019 o 17:41, LolikZabójca napisał:

Zrobiłem prosty skrypcik do sprawdzenia wątpliwości i już wszystko wiem. Dzięki wszystkim za pomoc. Dzięki @Threef, dzięki @gnysek!


@e: jednak pojawił się inny problem jeszcze... Teraz trzeba robić dodatkową operację w phpie sprwadzania shashowanych haseł. Czy da się porównywać hasła shashowane na etapie jeszcze mysql?

nie da się, musisz ściągnąć usera z bazy po loginie i z poziomu PHP porównać hasło z hashem

ogólnie lowerowanie loginu przy każdej próbie logowania to kiepski pomysł. Ogólnie robi się to tak, że loginy są case sensitive, ale obok nich jest pole username_canonical, gdzie jest już login znormalizowany - wszystko lowercasem. Przy rejestracji normalizujesz login i sprawdzasz czy istnieje taki username_canonical i już. Przy okazji artykuł jak złe rozegranie transformacji loginu może napsocić - https://labs.spotify.com/2013/06/18/creative-usernames/ (long story short - najprościej jeszcze ograniczyć loginy do znaków ASCII)

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy
Dnia 17.12.2019 o 14:56, LolikZabójca napisał:

Mogę do niej bez problemu zapisać wielkie i małe litery. Ale jak je rozróżnić? Kodowanie tabeli to UTF8_polish_ci

 

Zapisywanie tekstu, a metoda porównywania z zapytaniem SQL to są dwie różne rzeczy. Powyższe kodowanie przy zapytaniach nie odróżnia wielkości liter, chociaż zapisuje i zwraca je jak chcesz.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...