Come impostare la verifica dell'email utente dopo la registrazione?
Sai come tutti questi siti web inviano link ai loro nuovi utenti per verificare il loro indirizzo email? Sto cercando di impostare qualcosa di simile ma dopo alcune ricerche non ho ancora trovato una buona spiegazione su come implementarlo.
Sono aperto a suggerimenti sui plugin, tuttavia la maggior parte dei plugin che ho trovato hanno una tonnellata di altre funzionalità di cui non ho realmente bisogno.
Senza utilizzare un plugin, come potrei aggiungere questa funzionalità al mio codice?
Il mio approccio sarebbe quello di aggiungere un attributo 'Email non verificata' ai meta dati dell'utente dopo la registrazione e inviare un'email con una chiave di verifica all'utente. Come posso verificare se l'utente ha effettivamente cliccato su quel link?
Grazie per qualsiasi consiglio

Puoi utilizzare l'hook user_register
add_action( 'user_register', 'my_registration', 10, 2 );
function my_registration( $user_id ) {
// ottieni i dati dell'utente
$user_info = get_userdata($user_id);
// crea un codice md5 da verificare successivamente
$code = md5(time());
// crea un codice da inviare all'utente via email
$string = array('id'=>$user_id, 'code'=>$code);
// crea il codice di attivazione e lo stato di attivazione
update_user_meta($user_id, 'account_activated', 0);
update_user_meta($user_id, 'activation_code', $code);
// crea l'URL
$url = get_site_url(). '/my-account/?act=' .base64_encode( serialize($string));
// modificheremo qui per renderlo più elegante
$html = 'Clicca sui seguenti link <br/><br/> <a href="'.$url.'">'.$url.'</a>';
// invia un'email all'utente
wp_mail( $user_info->user_email, __('Oggetto dell\'email','text-domain') , $html);
}
Puoi controllare $_GET['act']
e poi attivare l'account se si tratta di una chiave valida aggiornando il valore meta account_activated
. Puoi utilizzare l'hook wp_authenticate_user
per verificare lo stato di attivazione ogni volta che un utente tenta di effettuare il login.
Frammento per la validazione:
add_action( 'init', 'verify_user_code' );
function verify_user_code(){
if(isset($_GET['act'])){
$data = unserialize(base64_decode($_GET['act']));
$code = get_user_meta($data['id'], 'activation_code', true);
// verifica se il codice fornito corrisponde al nostro
if($code == $data['code']){
// aggiorna il meta dell'utente
update_user_meta($data['id'], 'is_activated', 1);
wc_add_notice( __( '<strong>Successo:</strong> Il tuo account è stato attivato! ', 'text-domain' ) );
}
}
}

Ragazzi, penso che il metodo sopra menzionato introduca vulnerabilità di sicurezza che non dovrebbero esserci.
L'obiettivo principale della verifica email è assicurarci che le persone che si registrano forniscano un indirizzo email reale di cui sono proprietari o almeno a cui hanno accesso. Non vogliamo che le persone si registrino con, diciamo, un indirizzo email casuale di proprietà di qualcun altro, per esempio il vostro indirizzo email.
Il codice sopra presenta vulnerabilità che potrebbero permettere a un hacker di registrare un indirizzo email casuale di proprietà di qualcun altro e poi forzare abbastanza facilmente i valori $user_id e $code nella pagina di verifica email.
1a vulnerabilità
State usando $user_id. So che questo valore potrebbe essere qualsiasi cosa, ma tipicamente sarà un intero, specialmente se usate WordPress, che è circa il 30% dei siti internet, e guardando il codice PHP sopra, è effettivamente basato su WordPress. L'hacker riceve il suo $user_id come parte del processo di registrazione oppure lo indovina tramite brute force, semplicemente procedendo in sequenza partendo dal numero 1 e continuando con 2, 3, 4, 5, 6... Indovinerà il suo $user_id in meno di un giorno, forse anche in meno di un'ora se il vostro sito non ha molti membri.
2a vulnerabilità
State creando un $code usando la funzione di hash MD5 e l'ora di registrazione. L'hacker sa a che ora si è registrato. Diciamo che l'hacker si registra alle 15:00. Ora tutto ciò che deve fare è fare l'hash MD5 degli orari dalle 14:55 alle 15:05 e forzerà il $code in meno di un'ora.
Considerando quanto sopra, l'hacker può semplicemente forzare $user_id e $code in meno di un giorno e verificare un indirizzo email di cui non è proprietario
tsk tsk tsk
Un approccio migliore sarebbe generare un $code con la funzione rand() usando maiuscole (A-Z), minuscole (a-z), numeri (0-9) e caratteri speciali es. (!&#). Quella funzione di hash MD5 usa solo numeri 0-9 e lettere minuscole a-f e il modo in cui la state usando, basandovi sull'ora di registrazione, lo rende incredibilmente facile da restringere e attaccare con brute force.
Ho scritto il seguente codice PHP per generare un $code casuale con Lettere Maiuscole/Minuscole/Interi/Caratteri Speciali. Non rendetela così facile per gli hacker, ragazzi.
function generateRandomString($stringLength){
//specifica i caratteri da usare per generare la stringa casuale, non includere caratteri che WordPress non permette nella creazione
$characters = "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_[]{}!@$%^*().,>=-;|:?";
//ottieni la lunghezza totale dei caratteri specificati da usare per generare la stringa casuale
$charactersLength = strlen($characters);
//dichiara una stringa che useremo per creare la stringa casuale
$randomString = '';
for ($i = 0; $i < $stringLength; $i++) {
//genera caratteri casuali
$randomCharacter = $characters[rand(0, $charactersLength - 1)];
//aggiungi i caratteri casuali alla stringa casuale
$randomString .= $randomCharacter;
};
//sanitize_user, per sicurezza
$sanRandomString = sanitize_user($randomString);
//controlla che la stringa casuale contenga Maiuscole/Minuscole/Interi/Caratteri Speciali e che abbia la lunghezza corretta
if ( (preg_match('([a-zA-Z].*[0-9]|[0-9].*[a-zA-Z].*[_\W])', $sanRandomString)==1) && (strlen($sanRandomString)==$stringLength) )
{
//restituisce la stringa casuale se soddisfa i criteri di complessità
return $sanRandomString;
} else {
//se la stringa casuale non soddisfa i criteri minimi, richiama la funzione
return call_user_func("generateRandomString",($stringLength) );
}
}//fine della funzione generateRandomString
//chiama la funzione per generare una stringa casuale con Lettere Maiuscole/Minuscole/Interi/Caratteri Speciali
//nella funzione passiamo la lunghezza della stringa richiesta, in questo esempio genererà una stringa di 32 caratteri
$code = generateRandomString(32);
echo $code;

Ottima risposta! Sarebbe ancora un po' migliore se formattassi un po' il codice. Inoltre il $ deve essere escapato. Inoltre, correggimi se sbaglio, ma non c'è motivo di usare call_user_func
invece di chiamare direttamente la funzione.

Il motivo per cui uso call_user_function è che la funzione crea una stringa casuale della lunghezza specificata. Nel caso in cui i criteri di complessità della stringa casuale non siano soddisfatti, la funzione verrà semplicemente eseguita nuovamente automaticamente, ad esempio se la funzione generasse una stringa casuale che non contiene una lettera maiuscola o un numero, allora call_user_function esegue nuovamente la funzione. La funzione restituirà una stringa casuale solo quando soddisfa tutti i criteri di complessità.

Ho testato l'uso di base_64_encode sul $code generato dalla funzione di stringa casuale allegata a $url e poi recuperato con il metodo GET senza problemi.

Anche l'idea di inviare direttamente il $code a get_user_meta è molto negativa, poiché equivale a memorizzare password in testo semplice in un database. Dovresti crittografare il $code memorizzato in get_user_meta. Poi decrittare utilizzando il $code allegato all'$url. Altrimenti hai completamente bypassato il punto principale della sicurezza di hashing delle password di WordPress. Guarda la tua tabella wp-users, nessuna password è memorizzata in testo semplice, quindi devi anche fare l'hash del $code per il reset della password prima di memorizzarlo. Usa la funzione password_hash() per crittografare e password_verify() per decrittare.

Non credo che un codice di attivazione utente debba necessariamente essere sottoposto ad hashing per essere sicuro. Se qualcuno accede al tuo database, i codici di attivazione utente non contano davvero, possono semplicemente impostare l'email come confermata, anche se probabilmente hanno in mente cose molto peggiori. Riguardo a call_user_function
, ancora non capisco perché non puoi semplicemente chiamare la funzione da se stessa. Una funzione non può chiamare se stessa in PHP?

Sì, la funzione viene chiamata direttamente nel codice sopra dove dice "$code = generateRandomString(32);". La funzione utilizza preg match per verificare se la stringa casuale generata ha Lettere Maiuscole/Lettere Minuscole/Numeri/Caratteri Speciali. Se la stringa casuale non soddisfa i criteri di complessità, call_user_function esegue automaticamente nuovamente la funzione. La funzione continuerà a generare stringhe casuali finché una di esse non soddisfa i criteri di complessità specificati nel preg match. La prima stringa casuale potrebbe essere "abcdefghijklmnopqrstuvwxyzabcdef"

"abcdefghijklmnopqrstuvwxyzabcdef" non soddisfa i requisiti di complessità in quanto non contiene numeri, lettere maiuscole o caratteri speciali, quindi call_user_function richiama automaticamente la funzione finché non otteniamo una stringa casuale che soddisfi i requisiti di complessità. Si comporta come un ciclo.

Mi chiedo perché, se WordPress esegue l'hash della password dell'account nel database, non venga eseguito l'hash anche della chiave di reset per quella stessa password?

Pensi che WordPress non dovrebbe eseguire l'hash delle password degli account nel database?
