PHP – sposoby na przypomnienie hasła

W każdej witrynie, w której można się zarejestrować czasami zdarza się tak, że ktoś zapomni swojego hasła do konta.
W takiej sytuacji przydał by się skrypt / narzędzie do przypomnienia hasła. Jak go wykonać? Jest wiele dróg i sposobów na rozwiązanie tego problemu. Poniżej przedstawię kilka z nich.

Załóżmy ze mamy w bazie danych tabele z użytkownikami:
[code]Tabela:USERS
z polami: ID, login, password, email, code[/code]

Thank you for reading this post, don't forget to subscribe!

Oraz do wszystkich rozpatrywanych przypadków korzystamy z pliku: function.php, którego zawartość jest następująca:

<?php 
//tworzymy klasę

class funkcje{

// połączenie z bazą danych
function connect_bd(){
 $result= new mysqli('adres_bazy', 'user', 'haslo', 'nazwa_bazy');
 if (mysqli_connect_errno() === 0){
	$result -> query("SET NAMES 'utf8'");
   if (!$result) return false;
	else { 	return $result;	}
	}
  }

//funkcja zapisująca pojedynczy wynik z bazy do tablicy
public function get_single_shot($quest){
		$connect=$this->connect_bd();
		$result=$connect->query($quest);
		if (!$result){echo "blad w get single shot <br> w zapytaniu: ".$quest."<br>"; return false;}
		if ($result->num_rows>0)
		{
			$result_array=@$result->fetch_assoc();
			return $result_array;
		}
		else {
		return 0;
		}
	}
//zamyka klase
}
?>

Przypadek 1: przypomnienie hasła, które jest w formie niezakodowanej.

W tym przypadku aby zachować minimum wymaganej ostrożności, prosimy użytkownika o podanie adresu e-mail do swojego konta. Po podaniu prawidłowego adresu, na e-mail użytkownika wysyłane jest hasło do konta.
Tworzymy plik resetpass.php i wpisujemy:

 
<?php 
include_once 'function.php';

if (isset($_POST["wyslane"])) { // jeżeli formularz został wysłany, to wykonuje się poniższy skrypt
     
      // filtrowanie treści wprowadzonych przez użytkownika
     $email = htmlspecialchars(stripslashes(strip_tags(trim($_POST["email"]))), ENT_QUOTES);
     
            
      //korzystamy z naszej klasy   
     $get=new funkcje();
     $connect=$get->connect_bd();
   
     // system sprawdza czy prawidło zostały wprowadzone dane
      if (!eregi("^[0-9a-z_.-]+@([0-9a-z-]+\.)+[a-z]{2,4}$", $email)) {
                $blad=1;
                echo '<p class="blad"> Proszę wprowadzić poprawnie adres email.</p>';
        } else {
        	//sprawdzanie czy istnieje w bazie podany email
            	$sql1="SELECT login FROM USERS WHERE email='$email'";
            	$result1=$get->get_single_shot($sql1);
               
                if (isset($result1['login'])) {
                    $blad=0; //jeli istnieje login blad=0
                   
                }else {
                	//jesli nie istnieje konto blad=1
                	echo '<p class="blad">Konto o podanym adresie e-mail nie istnieje!</p>';
                	$blad=1; 
                }
            }
	// jesli email istnieje i nie ma żadnego błedu, wysylany zostaje email z haslem
            if ($blad == 0) {
     
            
     			$sql2="select password, login from USERS where email='$email'";
     			
                $result=$get->get_single_shot($sql2);
                
                if ($result) {
                	// zapisywanie w zmiennej $list zawartosci tresci email
                    $list = "Witaj! <br>
					Hasło dla konta: ".$result['login']." <br>
               		to: ".$result['password'];
                   
                   
                   $headers="From: <admin@nazwa_strony.pl>".PHP_EOL;
                   $headers.= 'MIME-Version: 1.0' .PHP_EOL;
                   $headers.="Content-type: text/html; charset=utf-8".PHP_EOL;
                   $headers.="X-Mailer: PHP/". phpversion();
                   
                   //proba wyslania emaila z danymi                   
                   if(mail($email, "hasło do konta", $list,$headers)){
                   	
                   	
                    echo '<p>Hasło zostało wysłane e-mailem</p>';
                   //ustawiamy zmienna $ok na wartość 1
                   $ok=1;
                   }
                   else {
                   	echo"Błąd!! - skontaktuj sie z adminitratorami serwisu.";
                   }}}}
         // tworzenie formularza HTML w przypadku gdy zmienna $ok nie została ustawiona na wartosc 1
        if($ok!=1){
        ?>     
         <form action="../users/resetpaswd.php" method="post">
        <input type="hidden" name="wyslane" value="TRUE" />
        <fieldset class='register'><legend>E-mail:</legend>
        <div class='k1'>
	Wpisz swój adres e-mail podany przy rejestraji: 
        <input type="text" name="email"/>
        </div>
        </fieldset>
 
        <p class="submit">
       <input type="submit" value="Przypomnij hasło" />
        </p></form>
    <?php 
        } ?>

Przypadek 2: przypomnienie hasła, które jest w formie zakodowanej.

W przypadku kodowania haseł – nie mamy możliwości przesłania użytkownikowi jego aktualnego hasła. Więc co możemy w tej sytuacji zrobić?
Podam dwa rozwiązania.
W obu korzystamy z pliku resetpass.php którego treść wygląda następująco:

<?php 
include_once 'function.php';

if (isset($_POST["wyslane"])) { // jeżeli formularz został wysłany, to wykonuje się poniższy skrypt
     
      // filtrowanie treści wprowadzonych przez użytkownika
     $email = htmlspecialchars(stripslashes(strip_tags(trim($_POST["email"]))), ENT_QUOTES);
     //korzystamy z naszej klasy   
     $get=new funkcje();   
     // system sprawdza czy prawidło zostały wprowadzone dane
      if (!eregi("^[0-9a-z_.-]+@([0-9a-z-]+\.)+[a-z]{2,4}$", $email)) {
                $blad=1;
                echo '<p class="blad"> Proszę wprowadzić poprawnie adres email.</p>';
        } else {
        	//sprawdzanie czy istnieje w bazie podany email
            	$sql1="SELECT login FROM USERS WHERE email='$email'";
            	$result1=$get->get_single_shot($sql1);
               
                if (isset($result1['login'])) {
                    $blad=0; //jeli istnieje login blad=0
                   
                }else {
                	//jesli nie istnieje konto blad=1
                	echo '<p class="blad">Konto o podanym adresie e-mail nie istnieje!</p>';
                	$blad=1; 
                }
            }
	// jesli email istnieje i nie ma żadnego błedu, wysylany zostaje email z powiadomieniem o zmianie hasla
            if ($blad == 0) {
                $sql2="select code, login from USERS where email='$email'";
     		$result=$get->get_single_shot($sql2);
                
                if ($result) {
                	// zapisywanie w zmiennej $list zawartosci tresci email
                    $list = "Witaj! <br>
					Ktoś poprosił o wygenerowanie nowego hasła dla konta: ".$result['login']." <br>

					Jeśli jest to błąd, po prostu zignoruj tego e-maila, a nic się nie stanie. <br><br>

					Aby ustawić nowe hasło, przejdź pod poniższy adres:
				<br><br>
                   <a href='http://www.nazwa_strony.pl/veryfication.php?resetpaswd=yes&amp;user=".$result['login']."&amp;code=".$result['code']."' target='_blank'>www.nazwa_strony.pl/veryfication.php?resetpaswd=yes&amp;user=".$result['login']."&amp;code=".$result['code']."</a>";
                                      
                   $headers="From: <admin@nazwa_strony.pl>".PHP_EOL;
                   $headers.= 'MIME-Version: 1.0' .PHP_EOL;
                   $headers.="Content-type: text/html; charset=utf-8".PHP_EOL;
                   $headers.="X-Mailer: PHP/". phpversion();
                   
                   if(mail($email, "Ustawianie nowego hasła", $list,$headers)){
                   	
                   	
                    echo '<p>Odnośnik potwierdzający został wysłany e-mailem</p>';
                   
                   $ok=1;
                   }
                   else {
                   	echo"Błąd!! - skontaktuj się z administratorami serwisu.";
                   }}}}
     
        // tworzenie formularza HTML

        if($ok!=1){
        ?>
        <form action="../users/resetpaswd.php" method="post">
        <input type="hidden" name="wyslane" value="TRUE" />
        <fieldset class='register'><legend>E-mail:</legend>
        <div class='k1'>
	Wpisz swój adres e-mail podany przy rejestraji: 
        <input type="text" name="email"/>
        </div> </fieldset>
        <p class="submit">
       <input type="submit" value="Przypomnij hasło" />
       </p></form>
       <?php 
        }
?>

Rozwiązanie 1.
Prosimy użytkownika o podanie adresu e-mail konta. Jeśli podano prawidłowy e-mail, wysyłana zostaje wiadomość ze specjalnie spreparowanym linkiem do formularza w serwisie gdzie użytkownik będzie mógł sobie zmienić swoje hasło.
Tworzymy plik veryfication.php

  <?
  include_once 'function.php'; //dolaczanie pliku z klasa funkcje
  
  if ($_REQUEST['resetpaswd'] == 'yes') {
   	?><h2 class="title"> Resetowanie hasła: </h2> <div class="entry"><?php 
   	   if (isset($_POST["code"])) { // jeżeli formularz został wysłany, to wykonuje się poniższy skrypt
       		$login = htmlspecialchars(stripslashes(strip_tags(trim($_REQUEST["user"]))), ENT_QUOTES);
       		$code = htmlspecialchars(stripslashes(strip_tags(trim($_POST["code"]))), ENT_QUOTES);
            // filtrowanie treści wprowadzonych przez użytkownika
            $haslo = $_POST["password"];
            $haslo2 = $_POST["password2"];
  		    $get=new funkcje();
    		$connect=$get->connect_bd();
            // system sprawdza czy prawidło zostały wprowadzone dane
           $blad=0;
            if (strlen($haslo) < 6 or strlen($haslo) > 30 ) {
                $blad=1;
                echo '<p class="blad">Proszę poprawnie wpisać hasło (od 6 znaków do 30 znaków). </p>';
            }
            if ($haslo !== $haslo2) {
                $blad=1;
                echo '<p class="blad"> Podane hasła nie są ze sobą zgodne. </p>';
            }
   	    	 $quest="select login from USERS where login='$login' and code='$code'";
      		$result1=$get->get_single_shot($quest);
            if (isset($result1['login'])) {
                    $blad=0; 
                   
                }else {
                	 $blad=1;
                	  echo '<p class="blad">Błędny kod zmiany hasła</p>';
                	 
                }
            
     
            // jeżeli nie ma żadnego błedu, użytkownik zostaje zarejestronwany i wysłany do niego e-mail z linkiem aktywacyjnym
            if ($blad == 0) {
                $haslo = md5($haslo); // zaszyfrowanie hasla
				$quest="update USERS set password='$haslo' where login='$login'";
     			
                $result=$connect->query($quest);
                if ($result) {
                	echo "Hasło zostało zmienione";
                
             
               $ok=1;
                }
                else "wystąpił nieznany błąd - zmiany hasła";
            }
            
        }
   	
   	
   	
   	
   	
   	
   if($ok!=1){
   	
   	?>  
  
 
 
   <form action="http://www.kosmosnews.pl/users/veryfication.php?resetpaswd=yes&amp;user=<?php  echo $_REQUEST['user'];?>&amp;code=" method="post">
        <input type="hidden" name="code" value="<?php echo $_REQUEST['code'];?>" />
        
 
  <fieldset class='register'><legend>Hasło:</legend>
  <div class='k1'>
  Wpisz swoje hasło*:
  <input type="password" name="password"/>
  </div>
  <div class='k1'>
  Potwierdź hasło*:
  <input type="password" name="password2"/>
  </div>
  </fieldset>
 
  
 
 <p class="submit">
      <input type="submit" value="Zapisz nowe hasło" />
   </p></form><?php }?>
  		 </div>
 		<?php 
   }else{
   echo " nie przekazano paremetrow - brak dzialania";
   }
   
   ?>

Rozwiązanie 2.
Prosimy użytkownika o podanie adresu e-mail konta. Jeśli podano prawidłowy e-mail, wysyłana zostaje wiadomość ze specjalnie spreparowanym linkiem do serwisu, gdzie po wejściu na wskazany link/adres strona wygeneruje automatycznie nowe hasło i prześle go do użytkownika.
Tworzymy plik veryfication.php

  
<?php
include_once 'function.php'; //dolaczanie pliku z klasa funkcje
  
  if ($_REQUEST['resetpaswd'] == 'yes') {
   	?><h2 class="title"> Resetowanie hasła: </h2> <div class="entry"><?php 
   	   if (isset($_REQUEST["code"])) { // jeżeli formularz został wysłany, to wykonuje się poniższy skrypt
   	   		// filtrowanie treści wprowadzonych przez użytkownika
       		$login = htmlspecialchars(stripslashes(strip_tags(trim($_REQUEST["user"]))), ENT_QUOTES);
       		$code = htmlspecialchars(stripslashes(strip_tags(trim($_REQUEST["code"]))), ENT_QUOTES);
            
           
  		 $get=new funkcje();
    		$connect=$get->connect_bd();
            // system sprawdza czy prawidło zostały wprowadzone dane
           $blad=0;
           
   	    	 $quest="select login from USERS where login='$login' and code='$code'";
      		$result1=$get->get_single_shot($quest);
            if (isset($result1['login'])) {
                    $blad=0; 
                   
                }else {
                	 $blad=1;
                	  echo '<p class="blad">Błędny kod zmiany hasła</p>';
                	 
                }
            
     
            // jeżeli nie ma żadnego błedu, użytkownik zostaje zarejestronwany i wysłany do niego e-mail z linkiem aktywacyjnym
            if ($blad == 0) {
            	$czyste_haslo=uniqid('kod'); // generowanie losowego hasla - z poczatkowa wartoscia kod
                $haslo = md5($czyste_haslo); // zaszyfrowanie hasla
		$quest="update USERS set password='$haslo' where login='$login'"; // zapytanie do bazy o aktualizacje zmiany hasła
     		$result=$connect->query($quest); // wysłanie zapytania
                  if ($result) {//jesli ok to wysylany zostaje email z nowych haslem 
                    $list = " Witaj! Oto twoje dane do konta <br>
					Nazwa użytkownika: ".$result['login']." <br>
					Nowe hasło: ".$czyste_haslo." <br> ";
                   
                   
                   $headers="From: <admin@nazwa_strony.pl>".PHP_EOL;
                   $headers.= 'MIME-Version: 1.0' .PHP_EOL;
                   $headers.="Content-type: text/html; charset=utf-8".PHP_EOL;
                   $headers.="X-Mailer: PHP/". phpversion();
                   
                   if(mail($email, "Nowe hasło", $list,$headers)){
                   	
                   	
                    echo '<p>Nowe hasło zostało wysłane!</p>';
                   
                 
                   }
                   else {
                   	echo"Błąd!! - skontaktuj sie z adminitratorami serwisu.";
                   }
                }
            }
            
        }
   }else{
   echo " nie przekazano paremetrow - brak dzialania";
   } ?>

I to by było na tyle. W razie gdybyście zauważyli jakiś błąd to proszę o info. Pisałem z ręki nie sprawdzając czy wszystko działa wiec jakaś literówka mogła się zdarzyć.