Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Zmiana hasła - jak zmieniać na nowe hasło jeżeli stare się zgadza?
Forum PHP.pl > Forum > Przedszkole
poplop
Witam,
mam problem. Mam skrypt, który zmienia hasło. Fajnie ale jest tylko jedno pole "Nowe hasło" i nawet nie sprawdza czy stare hasło się zgadza.
oto skrypt:
  1. <?php
  2.  
  3. require 'header.php'; // Dołącz początkowy kod HTML
  4. require 'config.php'; // Dołącz plik konfiguracyjny i połączenie z bazą
  5. require_once 'user.class.php';
  6.  
  7. /**
  8.  * Sprawdź czy formularz został wysłany
  9.  */
  10. if ($_POST['send'] == 1) {
  11. // Zabezpiecz dane z formularza przed kodem HTML i ewentualnymi atakami SQL Injection
  12. $pass = mysql_real_escape_string(htmlspecialchars($_POST['pass']));
  13.  
  14. // Zapisz dane użytkownika o podanym ID, do zmiennej $profile
  15. $id = $_GET['id'];
  16.  
  17. /**
  18.   * Jeśli wystąpiły jakieś błędy, to je pokaż
  19.   */
  20. if ($errors != '') {
  21. echo '<p class="error">Zmiana hasła nie powiodła się:<br />'.$errors.'</p>';
  22. }
  23.  
  24. else {
  25. // Posól i zasahuj hasło
  26. $pass = user::passSalter($pass);
  27. // Zapisz dane do bazy
  28. mysql_query("UPDATE `users` SET `id`='$id',`pass`='$pass' WHERE 1;") or die ('<p class="error">Wystąpił błąd podczas zmiany hasła.</p>');
  29. echo '<p class="success">Hasło zostało poprawnie zmienione</p>';
  30. }
  31. }
  32. ?>
  33.  
  34. <?php
  35. if (user::isLogged()) {
  36. echo '<center><form method="post" action="">
  37. <label for="pass">Nowe hasło:</label>
  38. <input maxlength="32" type="password" name="pass" id="pass" />
  39. <input type="hidden" name="send" value="1" />
  40. <input type="submit" value="Zmień" />
  41. </form></br>
  42. <a href="panel.php">Wróć do panelu</a>';
  43. }
  44.  
  45. else {
  46.  
  47. echo 'Funkcja dostępna tylko dla zalogowanych. <a href="index.php">Logowanie</a>';
  48. }
  49.  
  50. ?>

W czym potrzebuję pomocy?
Chcę aby było nowe pole "Stare hasło" i będzie trzeba je uzupełnić i jeżeli hasło będzie zgodne z tym w bazie to hasło zmienia się na hasło z pola "nowe hasło".
Chyba dokładnie wyjaśniłem. Chodzi mi tylko o funkcje sprawdzania hasła w bazie i przepuszczania, bo dodanie pola do formularza to nie problem.
Mam nadzieję że dobrze wyjaśniłem.

Pozdrawiam.
Damonsson
Masz w klasie do logowania sprawdzanie hasła, wystarczy skopiować część odpowiedzialną za sprawdzanie hasła i voila.
poplop
Cytat(Damonsson @ 2.04.2013, 09:17:55 ) *
Masz w klasie do logowania sprawdzanie hasła, wystarczy skopiować część odpowiedzialną za sprawdzanie hasła i voila.

Zrobiłem tak jak napisałeś i niestety źle to wychodzi ;/
Owszem działało że zmienia hasło jeżeli stare się zgadza ale zmieniało na hasło źle posolone i nie dało się zalogować tym nowym hasłem :/

Oto edytowany skrypt:
  1. <?php
  2.  
  3.  
  4. require 'header.php'; // Dołącz początkowy kod HTML
  5. require 'config.php'; // Dołącz plik konfiguracyjny i połączenie z bazą
  6. require_once 'user.class.php';
  7.  
  8. /**
  9.  * Sprawdź czy formularz został wysłany
  10.  */
  11. if ($_POST['send'] == 1) {
  12. // Zabezpiecz dane z formularza przed kodem HTML i ewentualnymi atakami SQL Injection
  13. $pass = mysql_real_escape_string(htmlspecialchars($_POST['pass']));
  14.  
  15. // Zapisz dane użytkownika o podanym ID, do zmiennej $profile
  16. $id = $_GET['id'];
  17.  
  18. // Posól i zasahuj hasło
  19. $pass = user::passSalter($pass);
  20. // Posól i zasahuj hasło
  21. $newpass = user::passSalter($newpass);
  22.  
  23. /**
  24.   * Jeśli wystąpiły jakieś błędy, to je pokaż
  25.   */
  26. if ($errors != '') {
  27. echo '<p class="error">Zmiana hasła nie powiodła się:<br />'.$errors.'</p>';
  28. }
  29.  
  30. // Sprawdź, czy użytkownik o podanym haśle isnieje w bazie danych
  31. $userExists = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM users WHERE id = '$id' AND pass = '$pass'"));
  32.  
  33. if ($userExists[0] == 0) {
  34. // Użytkownik nie istnieje w bazie
  35. echo '<center><p class="error">Hasło nie zostało zmienione - podałeś złe hasło!</p></center>';
  36. }
  37.  
  38. else {
  39.  
  40. // Zapisz dane do bazy
  41. mysql_query("UPDATE `users` SET `id`='$id',`pass`='$newpass' WHERE 1;") or die ('<p class="error">Wystąpił błąd podczas zmiany hasła.</p>');
  42. echo '<p class="success">Hasło zostało poprawnie zmienione</p>';
  43. }
  44. }
  45. ?>
  46.  
  47. <?php
  48. if (user::isLogged()) {
  49. echo '<center><form method="post" action="">
  50. <label for="pass">Stare hasło:</label>
  51. <input maxlength="32" type="password" name="pass" id="pass" />
  52. <label for="newpass">Nowe hasło:</label>
  53. <input maxlength="32" type="password" name="newpass" id="newpass" />
  54. <input type="hidden" name="send" value="1" />
  55. <input type="submit" value="Zmień" />
  56. </form></br>
  57. <a href="panel.php">Wróć do panelu</a>';
  58. }
  59.  
  60. else {
  61.  
  62. echo 'Funkcja dostępna tylko dla zalogowanych. <a href="index.php">Logowanie</a>';
  63. }
  64.  
  65. ?>
!*!
A co w tym złego że nowe hasło ma sól? wywal wtedy to
  1. $newpass = user::passSalter($newpass);
choć to ryzykowne.
poplop
Cytat(!*! @ 2.04.2013, 11:29:21 ) *
A co w tym złego że nowe hasło ma sól? wywal wtedy to
  1. $newpass = user::passSalter($newpass);
choć to ryzykowne.

Nic złego. Nie o to chodziło.
Jest coś źle w kodzie. Wpisuje stare hasło, ono się zgadza, więc zmienia hasło na nowe.
Zmieniając hasło na nowe ono się soli, ale chyba coś idzie nie tak, ponieważ zamiast zmienić to hasło na nowe poprawnie posolone wychodzi źle i przez to nie mogę się zalogować ponownie do panelu - muszę zmieniać hasło ręcznie w PhpMyAdmin.
ssstrz
Zapis do bazy jest poprawny?
  1. // Zapisz dane do bazy
  2. mysql_query("UPDATE `users` SET `id`='$id',`pass`='$newpass' WHERE 1;")

przypisujesz każdemu userowi to samo id (w postaci stringu) i nowe hasło.
poplop
Cytat(ssstrz @ 2.04.2013, 12:36:42 ) *
Zapis do bazy jest poprawny?
  1. // Zapisz dane do bazy
  2. mysql_query("UPDATE `users` SET `id`='$id',`pass`='$newpass' WHERE 1;")

przypisujesz każdemu userowi to samo id (w postaci stringu) i nowe hasło.

Tak jest poprawny. Jeżeli wywalę sprawdzanie starego hasła i zostanie tylko ustawienie nowego to wszystko dobrze się zmienia w bazie. Problem jest ze sprawdzaniem nowego + jego soleniem.
Id jest pobierane z adresu, a przed wejściem na stronę zmiany hasła zostaje pobrane id z bazy danych.
ssstrz
no skoro jesteś pewien, że ten zapis jest ok:
  1. mysql_query("UPDATE `users` SET `id`='$id',`pass`='$newpass' WHERE 1;")

i nic nie da jak zamienisz na ten kod:
  1. mysql_query("UPDATE `users` SET `pass`='$newpass' WHERE `id`='$id';")
poplop
Cytat(ssstrz @ 2.04.2013, 13:13:18 ) *
no skoro jesteś pewien, że ten zapis jest ok:
  1. mysql_query("UPDATE `users` SET `id`='$id',`pass`='$newpass' WHERE 1;")

i nic nie da jak zamienisz na ten kod:
  1. mysql_query("UPDATE `users` SET `pass`='$newpass' WHERE `id`='$id';")

Okej, zgadzam się, twoje zapytanie jest poprawne. Ale moje działało i myślałem że jest dobrze, a ja dopiero zaczynam. Dostajesz pomógł wink.gif
No ale czemu nowe hasło źle się soli i potem nie można się zalogować?
ssstrz
soli się dobrze ale robisz coś niedobrego z id w tabelce users, id to pewnie primary key więc to zapytanie robi mniej więcej taki błąd (mysql)
  1. UPDATE User SET idUser=1 WHERE idUser=2;
  2. ERROR 1557 (23000): Upholding FOREIGN KEY constraints FOR TABLE 'User', entry '1', KEY 1 would lead TO a duplicate entry

chcesz nadać wszystkim id tą samą liczbę, a nie wolno.
http://www.w3schools.com/sql/sql_primarykey.asp#gsc.tab=0
artuross
Moze nie poprawnie zapisujesz? Tzn. moze haslo wygenerowane przez Ciebie nie ma takiego samego algorytmu sprawdzania jak haslo uzywane do logowania?
poplop
Cytat(artuross @ 2.04.2013, 13:31:00 ) *
Moze nie poprawnie zapisujesz? Tzn. moze haslo wygenerowane przez Ciebie nie ma takiego samego algorytmu sprawdzania jak haslo uzywane do logowania?

Raczej nie, wszystko jest chyba dobrze użyte. Sprawdzałem plik logowania i tworzenia użytkownika i wykorzystywałem tamte funkcje.
Jak napisałem skrypt z podaniem tylko nowego hasła bez sprawdzania starego wszystko dobrze się zmienia.
A oto ten skrypt:
  1. <?php
  2.  
  3. require 'header.php'; // Dołącz początkowy kod HTML
  4. require 'config.php'; // Dołącz plik konfiguracyjny i połączenie z bazą
  5. require_once 'user.class.php';
  6.  
  7. /**
  8.  * Sprawdź czy formularz został wysłany
  9.  */
  10. if ($_POST['send'] == 1) {
  11. // Zabezpiecz dane z formularza przed kodem HTML i ewentualnymi atakami SQL Injection
  12. $pass = mysql_real_escape_string(htmlspecialchars($_POST['pass']));
  13.  
  14. // Zapisz dane użytkownika o podanym ID, do zmiennej $profile
  15. $id = $_GET['id'];
  16.  
  17. /**
  18.   * Jeśli wystąpiły jakieś błędy, to je pokaż
  19.   */
  20. if ($errors != '') {
  21. echo '<p class="error">Zmiana hasła nie powiodła się:<br />'.$errors.'</p>';
  22. }
  23.  
  24. else {
  25. // Posól i zasahuj hasło
  26. $pass = user::passSalter($pass);
  27. // Zapisz dane do bazy
  28. mysql_query("UPDATE `users` SET `pass`='$newpass' WHERE `id`='$id';") or die ('<p class="error">Wystąpił błąd podczas zmiany hasła.</p>');
  29. echo '<p class="success">Hasło zostało poprawnie zmienione</p>';
  30. }
  31. }
  32. ?>
  33.  
  34. <?php
  35. if (user::isLogged()) {
  36. echo '<center><form method="post" action="">
  37. <label for="pass">Hasło:</label>
  38. <input maxlength="32" type="password" name="pass" id="pass" />
  39. <input type="hidden" name="send" value="1" />
  40. <input type="submit" value="Zmień" />
  41. </form></br>
  42. <a href="panel.php">Wróć do panelu</a>';
  43. }
  44.  
  45. else {
  46.  
  47. echo 'Funkcja dostępna tylko dla zalogowanych. <a href="index.php">Logowanie</a>';
  48. }
  49.  
  50. ?>


A to skrypt z sprawdzaniem starego hasła i jeżeli ono się zgadza to zmienia na nowe - no i tu jest problem bo zapisuje jakoś inaczej zakodowane hasło (nie wiem czemu).
Oto kod:
  1. <?php
  2.  
  3. require 'header.php'; // Dołącz początkowy kod HTML
  4. require 'config.php'; // Dołącz plik konfiguracyjny i połączenie z bazą
  5. require_once 'user.class.php';
  6.  
  7. /**
  8.  * Sprawdź czy formularz został wysłany
  9.  */
  10. if ($_POST['send'] == 1) {
  11. // Zabezpiecz dane z formularza przed kodem HTML i ewentualnymi atakami SQL Injection
  12. $pass = mysql_real_escape_string(htmlspecialchars($_POST['pass']));
  13.  
  14. // Zapisz dane użytkownika o podanym ID, do zmiennej $profile
  15. $id = $_GET['id'];
  16.  
  17. // Posól i zasahuj hasło
  18. $pass = user::passSalter($pass);
  19. // Posól i zasahuj hasło
  20. $newpass = user::passSalter($newpass);
  21.  
  22. /**
  23.   * Jeśli wystąpiły jakieś błędy, to je pokaż
  24.   */
  25. if ($errors != '') {
  26. echo '<p class="error">Zmiana hasła nie powiodła się:<br />'.$errors.'</p>';
  27. }
  28.  
  29. // Sprawdź, czy użytkownik o podanym haśle isnieje w bazie danych
  30. $userExists = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM users WHERE id = '$id' AND pass = '$pass'"));
  31.  
  32. if ($userExists[0] == 0) {
  33. // Użytkownik nie istnieje w bazie
  34. echo '<center><p class="error">Hasło nie zostało zmienione - podałeś złe hasło!</p></center>';
  35. }
  36.  
  37. else {
  38.  
  39. // Zapisz dane do bazy
  40. mysql_query("UPDATE `users` SET `pass`='$newpass' WHERE `id`='$id';") or die ('<p class="error">Wystąpił błąd podczas zmiany hasła.</p>');
  41. echo '<p class="success">Hasło zostało poprawnie zmienione</p>';
  42. }
  43. }
  44. ?>
  45.  
  46. <?php
  47. if (user::isLogged()) {
  48. echo '<center><form method="post" action="">
  49. <label for="pass">Stare hasło:</label>
  50. <input maxlength="32" type="password" name="pass" id="pass" />
  51. <label for="newpass">Nowe hasło:</label>
  52. <input maxlength="32" type="password" name="newpass" id="newpass" />
  53. <input type="hidden" name="send" value="1" />
  54. <input type="submit" value="Zmień" />
  55. </form></br>
  56. <a href="panel.php">Wróć do panelu</a>';
  57. }
  58.  
  59. else {
  60.  
  61. echo 'Funkcja dostępna tylko dla zalogowanych. <a href="index.php">Logowanie</a>';
  62. }
  63.  
  64. ?>
!*!
W pierwszym skrypcie zapisujesz hasło ze zmiennej której nie ma?
poplop
Cytat(!*! @ 2.04.2013, 13:45:19 ) *
W pierwszym skrypcie zapisujesz hasło ze zmiennej której nie ma?

Nie, nie, nie. Źle skopiowałem, zamiast $newpass, powinno być $pass.
!*!
To od początku, co zawiera $pass i $newpass jak potraktujesz je var_dump()? Są takie same?
poplop
Cytat(!*! @ 2.04.2013, 13:52:06 ) *
To od początku, co zawiera $pass i $newpass jak potraktujesz je var_dump()? Są takie same?

Stare hasło "jakub"
Nowe hasło "jakub12345"
oto wyniki:
string(32) "c0ed90994f83f030a847e90e21903b6f"
string(32) "c7769ba163acebdf13ab5a232ab73a6a"
Niestety, jeżeli chcę się zalogować poprzez hasło "jakub12345" nie mogę, ponieważ niby podałem złe hasło.
!*!
Cytat
c7769ba163acebdf13ab5a232ab73a6a

I to jest w bazie, w tabeli pass Twojego ID? Po zmianie? Może coś przy logowaniu jest nie tak?
poplop
Cytat(!*! @ 2.04.2013, 14:11:31 ) *
I to jest w bazie, w tabeli pass Twojego ID? Po zmianie? Może coś przy logowaniu jest nie tak?

Tak, w bazie jest takie samo.
W takim razie proszę, oto skrypt logowania:
  1. <?php
  2.  
  3. require 'header.php';
  4. require 'config.php'; // Dołącz plik konfiguracyjny i połączenie z bazą
  5.  
  6. /**
  7.  * SKRYPT LOGOWANIA
  8.  */
  9. require_once 'user.class.php'; // Dołączamy rdzeń systemu użytkowników
  10.  
  11. // Zabezpiecz zmienne odebrane z formularza, przed atakami SQL Injection
  12. $login = htmlspecialchars(mysql_real_escape_string($_POST['login']));
  13. $pass = mysql_real_escape_string($_POST['pass']);
  14.  
  15. if ($_POST['send'] == 1) {
  16. // Sprawdź, czy wszystkie pola zostały uzupełnione
  17. if (!$login or empty($login)) {
  18. die ('<p class="error">Wypełnij pole z loginem!</p>');
  19. }
  20.  
  21. if (!$pass or empty($pass)) {
  22. die ('<p class="error">Wypełnij pole z hasłem!</p>');
  23. }
  24.  
  25. $pass = user::passSalter($pass); // Posól i zahashuj hasło
  26.  
  27. // Sprawdź, czy użytkownik o podanym loginie i haśle isnieje w bazie danych
  28. $userExists = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM users WHERE login = '$login' AND pass = '$pass'"));
  29.  
  30. if ($userExists[0] == 0) {
  31. // Użytkownik nie istnieje w bazie
  32. echo '<center><p class="error">Użytkownik o podanym loginie i haśle nie istnieje.</p></center>';
  33. }
  34.  
  35. else {
  36. // Użytkownik istnieje
  37. $user = user::getData($login, $pass); // Pobierz dane użytknika do tablicy i zapisz ją do zmiennej $user
  38.  
  39. // Przypisz pobrane dane do sesji
  40. $_SESSION['login'] = $login;
  41. $_SESSION['pass'] = $pass;
  42.  
  43. echo '<center><p class="success">Zostałeś poprawnie zalogowany... <META HTTP-EQUIV="Refresh" CONTENT="2;URL=panel.php"></p></center>';
  44. }
  45. }
  46.  
  47.  
  48. ?>
  49. <html>
  50. <title>DED-Panel - Logowanie</title>
  51. <link rel="stylesheet" type="text/css" href="styl.css" /></head>
  52. <form id="logostart"><img src="images/logo.png" alt="Logo" /></form>
  53. <form id="login1" action="" method="post">
  54. <h1>Logowanie</h1>
  55. <fieldset id="inputs">
  56. <input id="username" name="login" type="text" placeholder="Login" autofocus="" required="">
  57. <input id="password" name="pass" type="password" placeholder="Hasło" required="">
  58. </fieldset>
  59. <fieldset id="actions">
  60. <input type="hidden" name="send" value="1" />
  61. <input type="submit" id="submit" value="Zaloguj">
  62. </fieldset>
  63.  
  64. </form>
  65.  
  66. <!-- BSA AdPacks code -->
  67. <script src="js/jquery-1.6.3.min.js"></script>
  68.  
  69.  
  70. </body>
  71. </html>

Zaznaczam że dopiero raczkuje w PHP.
!*!
  1. $pass = mysql_real_escape_string($_POST['pass']);

Po co Ci ta funkcja, jak i tak hash leci do bazy?
poplop
Cytat(!*! @ 2.04.2013, 14:19:50 ) *
  1. $pass = mysql_real_escape_string($_POST['pass']);

Po co Ci ta funkcja, jak i tak hash leci do bazy?

A właśnie nie wiem.
Ale po dodaniu pod ta linijką takiego czegoś:
$newpass = mysql_real_escape_string($_POST['newpass']);

Wszystko działa prawidłowo.

A teraz jeszcze jedno pytanie, jak zabezpieczyć ten skrypt aby po zalogowaniu nie można było zmieniać hasła innym użytkownikom?
Chodzi o to że gdy jest np. index.php?id=10 i zmienię na index.php?id=5 to mogę mu normalnie zmienić hasło, a chciałbym temu zapobiec. Jak zrobić żebym mógł używać tylko swojego id, a do wszystkich innym zabroniony dostęp? Np. Id 5 nie jest twoje, nie możesz mu zmienić hasła.
!*!
Wywal te funkcje ze zmiennych $pass i $newpass bo są zbędne. Hasło jest hashowane, a w formularzu i tak go nie pokazujesz.

Cytat
A teraz jeszcze jedno pytanie, jak zabezpieczyć ten skrypt aby po zalogowaniu nie można było zmieniać hasła innym użytkownikom?
Chodzi o to że gdy jest np. index.php?id=10 i zmienię na index.php?id=5 to mogę mu normalnie zmienić hasło, a chciałbym temu zapobiec. Jak zrobić żebym mógł używać tylko swojego id, a do wszystkich innym zabroniony dostęp? Np. Id 5 nie jest twoje, nie możesz mu zmienić hasła.


Przy logowaniu zapisz ID w sesji i sprawdzaj czy ten z linki jest z nim równy, jak nie wyloguj. To najprostsza wersja i niezbyt dobra. Z czegoś lepszego, to zrezygnuj z liczb w linku, jako odnośniku do ID w bazie, możesz np. opierać się o ID z sesji, lub jak już musisz mieć coś w linku, to zamień liczby na string, coś jak generowany klucz na YT. 10 = wer2a4s (nie pamiętam jak ten proces się nazywa). Choć jak na początek opcja 1 i 2 będzie łatwiejsza do opanowania.
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.