Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Skrypt rejestracji problem
Forum PHP.pl > Forum > Przedszkole
porywacz
Witam, napisałem tak na szybko skrypt rejestracji na stronę. Jednak nie wiem czemu instrukcja wykonuje się nie tak jak chcę ;/
Wszystkie pola wypełniam zgodnie z kryteriami z preg_match a i tak wyskakuje mi komunikat z else'a ;///
Tutaj formularz w html:
  1. Wypełnij poniższy formularz, aby się zarejestrować.<br/>
  2. Pamiętaj, wypełniając formularz rejestracyjny wyrażasz zgodę na przetwarzanie twoich danych osobistych.
  3. <table style="text-align: right; margin-left: 20px;">
  4. <form method="post" action="zarejestruj.php">
  5. <tr><td></td><td>* Pola obowiązkowe</td></tr>
  6. <tr>
  7. <td>Nazwa użytkownika*:</td> <td><input type="text" name="login"/></td>
  8. </tr>
  9. <tr>
  10. <td>Hasło*: </td> <td><input type="password" name="password"/></td>
  11. </tr>
  12. <tr>
  13. <td>Powtórz hasło*: </td> <td><input type="password" name="password_rep"></td>
  14. </tr>
  15. <tr>
  16. <td>E-mail*: </td> <td><input type="text" name="email"></td>
  17. </tr>
  18. <tr>
  19. <td>Powtórz e-mail*: </td> <td><input type="text" name="email_rep"></td>
  20. </tr>
  21. <tr>
  22. <td></td> <td><input type="submit" value="Zarejestruj się"></td>
  23. </tr>
  24. </form>


A tutaj skrypt rejestracji:
  1. <?php
  2. $login = $_POST['login'];
  3. $password = $_POST['password'];
  4. $password = md5($password);
  5. $password_rep = $_POST['password_rep'];
  6. $password_rep = md5($password_rep);
  7. $email = $_POST['email'];
  8. $email_rep = $_POST['email_rep'];
  9.  
  10. if( !empty($login)
  11. &&
  12. !empty($password)
  13. &&
  14. !empty($password_rep)
  15. &&
  16. !empty($email)
  17. &&
  18. !empty($email_rep)
  19. ) {
  20. if(
  21. preg_match('@^[a-z0-9]{6,12}$@',$login)
  22. &&
  23. preg_match('!^[a-z0-9]{6,14}$!',$password)
  24. &&
  25. preg_match('!^[a-z0-9]{3,20}@[a-z0-9]{2,8}.[a-z]{2,5}$!',$email)) {
  26.  
  27. $db = mysql_connect('localhost','root','') or die('Nie udało się połączyć z serwerem :(');
  28. $db = mysql_select_db('uzytkownicy');
  29.  
  30. $query = mysql_query("INSERT INTO uzytkownicy (login, password, email) VALUES('$login','$password','$email')") or die('Nie udało się umieścić values w tabeli');
  31.  
  32. } else {
  33. echo('Nie udało mi się Ciebie zarejestrować. <br/> Sprawdź czy poprawnie wypełniłeś wszystkie pola.');
  34. }
  35. } else {
  36. echo('Wypełnij wszystkie pola !');
  37. }
  38. ?>

Z góry dziękuję za pomoc smile.gif
markonix
No a przetestowałeś po kolei każdy z "preg"?
Przez który nie przechodzi?
porywacz
Przetestowałem usuwając po jednym aż nie zostało nic z tych preg i działało sad.gif Więc to na pewno przez preg ale nie wiem dokładnie co zrobiłem źle ;/
markonix
To nie usuwaj wszystkie tylko po jednym...
No chyba, że wszystkie są złe...
porywacz
Ok, sprawdziłem i wyszło na to, że nie przechodzi przez preg_match, który sprawdza hasło ;d A wpisuję na przykład maslomaslo1 ; d
markonix
Chociaż nie pamiętam akurat co robią te wykrzykniki (myślałem, że to przez to) to i tak działa.
http://www.functions-online.com/preg_match.html

Druga sprawa to czemu ograniczasz znaki, które można użyć w haśle?
Jedyne co jest słuszne to sprawdzenie długości hasła (żeby nie było zbyt krótkie).
Druga sprawa hasła się nie zapisuje w jawnej postaci (to nie Allegro) tylko się tworzy hash (md5 i sha1 z tych takich podstawowych).
porywacz
markonix, to czemu u mnie nie działa ? ohmy.gif Dziwne ;((

  1. $password = $_POST['password'];
  2. $password = md5($password);


Przecież jest md5...
!*!
Trudno żeby działało, skoro generujesz md5 a sprawdzasz czy ma 14 znaków. Poza tym źle się do tego zabrałeś. Nie sprawdzasz czy formularz został wysłany, skoro używasz md5 to sprawdzanie hasła jest zbędne, no i nie sądzę że używanie pregów do sprawdzania długości ciągu jest dobre. Nie sprawdzasz też czy pola istnieją oraz jakiego są typu. I nie przepuści Ci wszytkich adresów email, chociaż są poprawne.
porywacz
  1. if( isset($login)
  2. &&
  3. isset($password)
  4. &&
  5. isset($password_rep)
  6. &&
  7. isset($email)
  8. &&
  9. isset($email_rep)
  10. )

Tak lepiej? biggrin.gif Skoro nie bardzo da się to zrobić pregami to może coś zasugerujecie? biggrin.gif
!*!
Nie, bo nie sprawdziłeś czy formularz został wysłany. Zlicz znaki np strlen, haszuj hasło md5/sha1 ale nie sprawdzaj ile ma znaków bo zawsze będzie mieć tyle samo 32(md5) lub 40(sha1). Popraw walidację adresu email, bo co z tymi które pochodzą z subdomen? cokolwiek.cos@cos.zxc.pl
porywacz
A jak sprawdzić czy formularz został wysłany? Myślałem, że sprawdzenie, czy istnieją dane pola w tablicy post jest jednoznaczne ze sprawdzeniem istnienia wysłanego formularza : O

O już działa wszystko. !*!, dziękuję, że mi to wyjaśniłeś biggrin.gif Zapomniałem, że shashowałem hasło przed sprawdzeniem preg_match haha.gif Wystarczyło przesunąć $password = md5($password) na koniec skryptu przed wprowadzeniem danych do bazy biggrin.gif
!*!
Po co Ty sprawdzasz te hasło przez pregi? Wywal to,bo skoro je haszujesz, to i tak ma tylko [a-z0-9] pregi nie są od liczenia ilości znaków, a !@#$%^&*( są wręcz wskazane w haśle. Formularz sprawdzasz przez $_POST['tu_nazwa_inputa_zformularza_ktory_wysyla'];
porywacz
Ehh nie zrozumiałeś ostatniego posta ;D Teraz te pregi nie sprawdzają zhashowanego hasła tylko te hasło, które zostało oryginalnie wprowadzone do inputa. Ale skoro to nie jest dobre rozwiązanie to jak sprawdzić ilość znaków w prawdziwym haśle (jeszcze nie zhashowanym) ?
!*!
Już Ci odpowiedziałem na to pytanie wyżej.
porywacz
W takim razie coś takiego "ujdzie" ?

  1. $strlen_haslo = strlen($password);
  2.  
  3. if(
  4. preg_match('@^[a-z0-9]{6,12}$@',$login)
  5. &&
  6. $strlen_haslo > 6
  7. &&
  8. $password == $password_rep
  9. &&
  10. preg_match('/^[a-z0-9]{3,20}@[a-z0-9]{2,8}.[a-z]{2,5}$/',$email)
  11. &&
  12. $email == $email_rep) {
markonix
Napisz to od nowa bo jeżeli to nie robisz tylko dla treningu to userbility tego kuleje.
Czemu?
Walisz całą weryfikacje do jednego warunku - czy ktoś wpiszę zły e-mail albo za krótkie hasło to będzie mu się wyświetlał ten sam błąd.
Jak lepiej?
Pomijając rzucanie wyjątków itp. najprostszy sposób to tablica $errors i taki system:
  1. if ($strlen_haslo < 6)
  2. $errors[] = 'Zbyt krótkie hasło';
  3. if (KOLEJNY WARUNEK)
  4. $errors[] = 'KOLEJNY BŁĄD';
  5.  
  6. if (count($errors))
  7. // wyświetl błędy
  8. else
  9. // dokonaj rejestracji


Potem count i foreach, którym wyświetlisz wszystkie błędy (np. w akapitach z klasą error).

Do walidacji e-mail stosuj filter_var, a nie wyrażeń regularnych.
porywacz
Markonix, dzięki za pomoc. Tobie także, !*! smile.gif
Już wszystko działa jak należy. YEAH biggrin.gif
!*!
Cytat(porywacz @ 9.04.2012, 18:58:37 ) *
W takim razie coś takiego "ujdzie" ?

  1. $strlen_haslo = strlen($password);
  2.  
  3. if(
  4. preg_match('@^[a-z0-9]{6,12}$@',$login)
  5. &&
  6. $strlen_haslo > 6
  7. &&
  8. $password == $password_rep
  9. &&
  10. preg_match('/^[a-z0-9]{3,20}@[a-z0-9]{2,8}.[a-z]{2,5}$/',$email)
  11. &&
  12. $email == $email_rep) {


Niczego nie zrozumiałeś. Ujdzie, ale to nie znaczy że jest dobrze, przeciwnie.
porywacz
Wiem, że nie jest tak dobrze, dlatego napisałem wszystko od nowa tak jak napisał markonix ^^
Tutaj skrypt:

  1. <?php
  2. $login = $_POST['login'];
  3. $password = $_POST['password'];
  4. $password_rep = $_POST['password_rep'];
  5. $email = $_POST['email'];
  6. $email_rep = $_POST['email_rep'];
  7.  
  8. $db = mysql_connect('localhost','root','') or die('Nie udało się połączyć z serwerem :(');
  9. $db = mysql_select_db('uzytkownicy');
  10.  
  11. $sprawdz_login = mysql_fetch_array(mysql_query("select count(*) from uzytkownicy where login = '$login' limit 1"));
  12. $sprawdz_email = mysql_fetch_array(mysql_query("select count(*) from uzytkownicy where email = '$email' limit 1"));
  13.  
  14. if( !empty($login)
  15. &&
  16. !empty($password)
  17. &&
  18. !empty($password_rep)
  19. &&
  20. !empty($email)
  21. &&
  22. !empty($email_rep)
  23. ) {
  24. if($sprawdz_login[0] >= 1) {
  25. $errors .= 'Ta nazwa użytkownika jest już zajęta<br/>';}
  26. if($sprawdz_email[0] >= 1) {
  27. $errors .= 'Taki email jest już zajęty<br/>';}
  28. if(strlen($password) < 6) {
  29. $errors .= 'Twoje hasło jest za krótkie<br/>';}
  30. if(strlen($login) < 6){
  31. $errors .= 'Twój login jest za krótki<br/>';}
  32. if(strlen($login) > 14) {
  33. $errors .= 'Twój login jest za długi<br/>';}
  34. if(!preg_match('/[a-z]/',$login)){
  35. $errors .= 'Twój login musi zawierać litery<br/>';}
  36. if($password !== $password_rep) {
  37. $errors .= 'Hasła się nie zgadzają<br/>';}
  38. if($email !== $email_rep) {
  39. $errors .= 'E-maile się nie zgadzają<br/>';}
  40.  
  41. if (count($errors)) {
  42. echo('Rejestracja nie powiodła się. Wystąpiły następujące błędy: <br/>'.$errors);
  43. } else {
  44. $password = md5($password);
  45. $password_rep = md5($password_rep);
  46. $query = mysql_query("INSERT INTO uzytkownicy (login, haslo, email) VALUES('$login','$password','$email')") or die('Nie udało się umieścić values w tabeli');
  47. }
  48. } else {
  49. echo('Rejestracja nie powiodła się. Wystąpiły następujące błędy: <br/>Wypełnij wszystkie pola !');
  50. } ?>


Może nie jest idealnie ale ważne, że działa. Akurat na tym chciałem się skupić, ponieważ jest to mój pierwszy skrypt rejestracji biggrin.gif
!*!
Prawie, sprawdź czy formularz został wysłany i zobacz jakie są różnice między empty() a isset(), sprawdzaj też czy zmienne to stringi, a i nie musisz robić połączenia na początku z bazą, rób je np. gdy login zostaje przesłany. Sprawdzaj to co jest potrzebne w danym momencie. No i teraz nie sprawdzasz czy email jest poprawny?wink.gif
porywacz
Znaczy się tak, to połączenie musiałem dać na górę bo na górze wyciągam z bazy rekordy dotyczące emailu i loginu, aby potem je sprawdzić w ifach.
Muszę jeszcze poczytać o filter_var i się zabiorę za dopracowywanie skryptu biggrin.gif Robię jeszcze dużo błędów ale jestem zadowolony, że wgl działa biggrin.gif "Bawię się" w programowanie w php od około miesiąca więc nie spodziewam się od razu bezbłędnych skryptów arrowheadsmiley.png

Wiem tyle, że funkcją empty() sprawdzam czy pole jest puste a funkcją isset(), czy dane pole istnieje. Nie wiem, chyba jestem jakimś tumanem ale nie wiem jak sprawdzić czy formularz został wysłany biggrin.gif
markonix
Po co linia:
  1. $password_rep = md5($password_rep);
?

Errory łączysz jako stringi ale propozycja z tablicą jest bardziej elastyczna.
Potem błędy możesz wyświetlić w dowolnej postaci (najpierw po enterach ale potem na pewno ktoś by wolał je wymienić od myślników albo jakieś divy).
Zamiast dawać wszędzie <br /> wystarczy implode.

Tym system sprawdzaj też czy pola są puste w takim schemacie.
  1. if (CZY PUSTY)
  2. $errors[] = 'Jest pusty';
  3. else if (CZY ZA KRÓTKI)
  4. $errors[] = 'Za krótki';


Dzięki temu nie wyświetlą się 2 błędy, które się pokrywają.

Żeby sprawdzić czy formularz został wysłany wystarczy isset na dowolnym polu z tego formularza ponieważ on zawsze daje true gdy formularz zostanie wysłany nawet gdy go nie wypełnimy. Ładniej można dać input z polem ukrytym.
  1. <input type="hidden" name="action" value="add_user" />

i rozpocząć skrypt od sprawdzenia czy $_POST['action'] == 'add_user.
porywacz
Próbowałem już sposobu z tablicą ale nie mogłem wyświetlić na końcu całości bez tej stryktury tabeli.
Wyglądało to tak:
Array ( errors[0] => Hasło jest za krótkie
Coś w tym stylu :/

A wyglądało to mniej więcej tak:

if ($strlen_haslo < 6) {
$errors[] = 'Zbyt krótkie hasło';}
if ($strlen_login < 6) {
$errors[] = 'Zbyt krótki login';}

if (count($errors)) {
print_r($errors);
}
else {
}
markonix
  1. foreach ($erorrs as $error) {
  2. echo '<p class="error">'. $error .'</p>';
  3. }

Nadaj w css jakieś ostylowanie dla kasy error, na początek wystarczy czerwony kolor.
md5_jest_slabe
md5 na obecne standardy jest uznawany za słaby algorytm hashujący i ma dość rozbudowaną bazę hashy, więc nie należy go stosować

https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet

zainteresuj się raczej PHPass używanym przez wordpress, phpbb3 i inne duże skrypty
!*!
Cytat(md5_jest_slabe @ 10.04.2012, 14:19:20 ) *
md5 na obecne standardy jest uznawany za słaby algorytm hashujący i ma dość rozbudowaną bazę hashy, więc nie należy go stosować


Pokaż mi jak "łamiesz" md5. thumbsdownsmileyanim.gif
kodepiko6
Cytat(!*! @ 10.04.2012, 15:14:19 ) *
Pokaż mi jak "łamiesz" md5. thumbsdownsmileyanim.gif


Jak zapewne wiesz, istnieją strony, które mają duże bazy danych i zawierają rozkodowane hashe md5, gdy user ma proste hasło, to zapewne znajdzie się w tej bazie.
Sam byłem zaskoczony, kiedy moje hasło składające się z ośmiu znaków z cyfrą, bez problemu odkodowałem za pomocą jednej z takich stron.

Ale w przypadku metody 'salt' szczególnie wewnątrz hasła bądź na początku-końcu, jest to o wiele bezpieczniejsze wyjście niż samo md5.
md5_jest_slabe
Dokładniej rzecz ujmując MD5 jest algorytmem słabym pod względem kryptograficznym, oznacza to że istnieje metoda szybsza niż brute-force by dostać plaintext hasha.

Niemniej jednak nie jest to istotą tego dlaczego używać się MD5 nie powinno.

Należy zwrócić uwagę na kontekst wykorzystania MD5. W tym przypadku do bezpiecznego przechowywania haseł, tak by bardzo ciężko było uzyskać tekst jawny hasła. Jest to pytanie kompleksowe i wieloaspektowe.

Kilka powodów dlaczego md5 nie jest bezpieczne:

1. istnieją strony np. http://www.freerainbowtables.com/ które w dość prosty sposób potrafią znaleźć jawny tekst niektórych haseł
2. ludzie używają w większości haseł o limitowanej długości co zmniejsza bazę wszystkich możliwych haseł
3. MD5 jest uniwersalny tj. hasło asd zawsze będzie miało hash taki sam, co jest wadą w przypadku przechowywania haseł bo wystarczy że ktoś zamieści taki hash z jawnym tekstem i jest problem, w przechowywaniu haseł chciało by się mieć pod tym względem jak najmniejszą uniwersalność.
4. MD5 jest stosunkowo szybkim i tanim do wykonania hashem, co ułatwia ataki brute-force. Hash przechowujący hasło powinien być jak najdroższy w rozsądnych ramach do wykonania. Należy do tego dodać podwajanie się liczby tranzystorów i mocy obliczeniowej za tym idącej.
5. Przeciętny użytkownik internetu ma hasło słownikowe, krótkie, łatwe do zapamiętania, co ułatwia udany atak na MD5.

Tak jak wspomniałem na wstępie, tu nie chodzi o to czy coś się złamie czy nie złamie, tylko czy spełni swoją funkcję w danym kontekście jej wykorzystania. MD5 nie spełnia swojej funkcji jako zabezpieczenie przed poznaniem tekstu jawnego hasła na podstawie hashu.

Zobacz chociażby na:

http://niebezpiecznik.pl/post/filmweb-pl-h...l-uzytkownikow/
https://devilteam.pl/viewtopic.php?f=88&t=6609
https://devilteam.pl/viewforum.php?f=88

Mam nadzieję że poniektórym to otworzy oczy.
!*!
Nie odpowiedziałeś. Twoje ogólniki mogą dotyczyć większości metod haszujących. Co z tego że są serwisy które posiadają bazę "słownikową" i po wprowadzeniu MD5 elegancko dostajesz odpowiedź. Skoro w praktycznie każdym serwisie hasze trzymasz jedynie w bazie, dodatkowo solisz je i nigdzie nie udostępniasz bo niby po co.

Nie ma czegoś takiego jak decode_md5(), bo to tylko porównanie istniejących wyników, które trzeba skądś pobrać/wprowadzić. Dlatego nie ma czegoś takiego "o a dzisiaj sobie podpatrzę hasło w md5, bo mi się nudzi". Jeśli koder i admin to ofermy, to już ich problem jak hasze z bazy wyciekną.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.