Completiamo il nostro lavoro con la pagina per il recupero della password, o meglio per la generazione di una nuova password casuale da inviare via email a chi l'avesse dimenticata. Procediamo quindi con l'aggiunta della rotta al fila app.yaml
:
- url: /recupera-password
script: recupera-password.php
La pagina per il recupero password avrà una struttura simile a quella di registrazione e il corpo della pagina sarà il medesimo:
<!doctype html>
<html lang="en">
<head>
<title>Google Cloud Platform: registrazione</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<?php echo $contenuto; ?>
</div>
<script src="/js/jquery-3.2.1.slim.min.js"></script>
<script src="/js/popper.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>
Useremo anche in questo caso una strategia di switch del codice in base al metodo d'accesso, ma personalizziamo il nome delle funzioni per rendere il codice più intuitivo:
if(strtolower($_SERVER['REQUEST_METHOD']) == 'post'){
$contenuto = invia();
}else{
$contenuto = form();
}
La creazione del form verrà ulteriormente semplificata, sarà sufficiente un solo campo dove l'utente inserirà l'email che useremo sia per l'inoltro del messaggio sia per l'aggiornamento del record:
function form(){
$str='<h1>Login</h1>
<form action="/recupera-password" method="post">
<label id="email">Email</label>
<input type="email" placeholder="Inserisci la tua email" name="email" id="email" class="form-control" required>
<br>
<div class="row">
<div class="mx-auto">
<button type="submit" class="btn btn-success">Invia</button>
</div>
</div>
</form>';
return $str;
}
Come anche negli altri casi la pagina eseguirà un post su se stessa. Per gestire il ricaricamento della pagina e le funzionalità connesse abbiamo bisogno di importare la connessione al database e la libreria per l'invio delle email:
use \google\appengine\api\mail\Message;
include('include/connessione.php');
L'obiettivo è quello di generare una nuova password casuale aggiornando il database e inviandola all'utente via email. Abbiamo quindi bisogno di una funzione per la generazione di password casuali:
function generatePassword ($length = 20){
$password = "";
$possible = "12346789bcdfghjkmnpqrtvwxyzBCDFGHJKLMNPQRTVWXYZ";
$maxlength = strlen($possible);
if ($length > $maxlength) {$length = $maxlength;}
$i = 0;
while ($i < $length) {
$char = substr($possible, mt_rand(0, $maxlength-1), 1);
if (!strstr($password, $char)) {
$password .= $char;
$i++;
}
}
return $password;
}
La funzione ha come unico parametro di input la lunghezza della password da ottenere, di default 20 caratteri. Ciascun carattere sarà estratto a caso da una lista, nell'esempio abbiamo solo numeri e lettere minuscole e maiuscole, ma potremmo aggiungere anche caratteri alfanumerici.
Ora recuperiamo l'email inviata dal form e operiamo una ricerca nella tabella utenti
, se abbiamo un record procediamo con fetch-assoc
e generiamo la password.
$db = connect();
$email = $_REQUEST['email'];
if ($email) {
$sql='SELECT id FROM utenti WHERE email=:email';
$stmt = $db->prepare($sql);
$stmt->execute([':email' => $email]);
if($stmt->rowCount() > 0){
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$pwd=generatePassword(10);
$hashedPwd = md5($pwd);
Non resta che concludere le operazioni aggiornando il record del database con l'hash della nuova password:
$sql = 'UPDATE utenti SET password="'.$hashedPwd.'" WHERE id=:id LIMIT 1';
$stmt = $db->prepare($sql);
$stmt->execute([':id' => $row['id']]);
Quindi comunichiamo all'utente la nuova password di accesso. Creiamo l'oggetto email
e assegniamo mittente, destinatario, oggetto e corpo del messaggio prima dell'invio:
$mail = new Message();
$mail->addTo([$email]);
$mail->setSender('info@test-guida-htmlit.appspotmail.com');
$mail->setSubject('Recupero password');
$mail->setTextBody('La tua nuova password è '.$pwd);
$mail->send();
Come ultimo passaggio rimandiamo l'utente alla pagina iniziale:
header('location: /');