PHP

Verifica Email

Sistema di registrazione con verifica email. L'utente registrato non potrà accedere finché non avrà cliccato sul link di attivazione inviato via email, validando così la proprietà dell'indirizzo inserito.

Durata

180 minuti

Software

XAMPP, Mailtrap (o server SMTP), VS Code

LOGIN | Verifica Email

Il processo di Attivazione dell'Utente

Un account "appena creato" deve essere in uno stato di sospensione. Per gestire questo processo, aggiungiamo due concetti chiave al nostro sistema:

Elemento Scopo
Colonna "attivo" Un valore booleano (0 o 1) nel DB che indica se l'utente può fare login.
Token Una stringa casuale alfanumerica inviata via mail per identificare la richiesta.
Link di attivazione Una URL che punta a uno script PHP passando il token come parametro GET.
Fasi dell'Attivazione account con invio email | PHP MySql | codice registrazione utente
LABORATORIO

Implementazione Double Opt-In


1 Aggiornamento Database

Dobbiamo aggiungere i campi per gestire lo stato e il codice di verifica:

ALTER TABLE utenti 
ADD COLUMN codice_conferma VARCHAR(100),
ADD COLUMN attivo TINYINT(1) DEFAULT 0;

2 Registrazione con invio codice (registrazione.php)

Modifichiamo la logica di inserimento per generare il token.


<?php
require "config.php";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $user = $_POST['username'];
    $email = $_POST['email'];
    $pass_sicura = password_hash($_POST['password'], PASSWORD_BCRYPT);
    
    // Generiamo un codice casuale univoco
    $token = bin2hex(random_bytes(16));

    $sql = "INSERT INTO utenti (username, email, password, codice_conferma, attivo) 
            VALUES (:u, :e, :p, :t, 0)";
    $stmt = $pdo->prepare($sql);
    
    if ($stmt->execute(['u' => $user, 'e' => $email, 'p' => $pass_sicura, 't' => $token])) {
        
        // Simulazione invio email (in un server reale useremmo mail())
        $link = "http://localhost/progetto/attiva.php?token=$token";
        echo "Registrazione effettuata! Clicca qui per simulare l'email: ";
        echo "<a href='$link'>Attiva Account</a>";
        
    } else {
        echo "Errore nella registrazione.";
    }
}
?>
1. Il rischio delle Query Dirette

Se scrivessi la query inserendo direttamente le variabili, il codice sarebbe questo:


// CODICE PERICOLOSO - NON USARE
$sql = "INSERT INTO utenti (username) VALUES ('$user')";

Il problema: Se un utente cattivo nel campo username scrivesse: '); DROP TABLE utenti; --, la tua query diventerebbe:
INSERT INTO utenti (username) VALUES (''); DROP TABLE utenti; --')
Il database eseguirebbe due comandi: l'inserimento e la cancellazione totale della tabella. Questo è un attacco di SQL Injection.

2. Come funzionano i Segnaposto (:u, :e, :p)

Quando usiamo $pdo->prepare($sql) con i segnaposto, accade qualcosa di magico in due step:

Fase Cosa succede
Preparazione Inviamo al database solo la "struttura" della query. Il DB capisce che deve fare un INSERT, ma non sa ancora cosa inserire.
Esecuzione Inviamo i dati separatamente con execute(). Il database li tratta esclusivamente come puro testo, togliendo loro ogni potere di eseguire comandi.
3. Vantaggi in sintesi
  • Sicurezza: I dati vengono "puliti" automaticamente (sanitizzazione).
  • Velocità: Se devi inserire 1000 utenti, il database analizza la query una sola volta e cambia solo i dati.
  • Pulizia: Non devi impazzire con apici singoli (') e doppi (") dentro le stringhe SQL.

3 Pagina di Attivazione (attiva.php)

Questa pagina riceve il codice via GET, cerca l'utente e lo attiva.


<?php
require "config.php";

if (isset($_GET['token'])) {
    $token = $_GET['token'];

    // Cerchiamo l'utente con quel token
    $sql = "SELECT id FROM utenti WHERE codice_conferma = :t AND attivo = 0";
    $stmt = $pdo->prepare($sql);
    $stmt->execute(['t' => $token]);

    if ($stmt->rowCount() > 0) {
        // Utente trovato! Lo attiviamo e cancelliamo il token
        $update = "UPDATE utenti SET attivo = 1, codice_conferma = NULL WHERE codice_conferma = :t";
        $pdo->prepare($update)->execute(['t' => $token]);
        
        echo "<h2>Account attivato con successo!</h2>";
        echo "<p>Ora puoi effettuare il <a href='login.php'>Login</a>.</p>";
    } else {
        echo "Codice non valido o account già attivo.";
    }
} else {
    echo "Accesso non consentito.";
}
?>

4 Esercitazione: Protezione del Login

Task: Ora che abbiamo il campo attivo, dobbiamo modificare la futura pagina login.php. Non basta più controllare che la password sia corretta; nella query di login dobbiamo aggiungere una condizione: l'utente deve avere attivo = 1.

  • Prova a scrivere la query SQL che seleziona l'utente solo se lo username corrisponde E il campo attivo è uguale a 1.





Email Verification, Token, Account Activation, PHP,