Autenticazione PHP/OOP campi vuoti

Odi la OOP e ti ostini a volerla usare, in realtà non la stai sfruttando affatto, stai solo mettendo delle funzoni procedurali dentro a classi, fossi in te eviterei e userei la procedurale che poi non è mica vergognoso usarla :)
Borgo ti ha giustamente detto di passare a mysql improvved o a PDO per un semplice motivo, la vecchia funzionalità è pericolosa, infatti tu non fai nessun escape sui dati in ingresso, dai per scontato che i dati siano sempre giusti, ad esempio $nome_utente lo infili nella query senza nemmeno fare un escape.
Eppure usando $nome_utente = mysql_escape_string($nome_utente) ovvero usandola su igni dato in ingresso alla query ti permette di stare ragionevolmente sicuro su ciò che viene inserito dagli utenti e l'integrità del tuo database :)
 
No in realtà non ho detto di odiare la programmazione a oggetti (anzi per le potenzialità forse mi piace anche di più), il punto è che me in realtà servirebbe proprio quello che dici/dite cioè un sistema sicuro dove ogni dato inserito sia verificato e corretto.
Ma come dicevo nei commenti precedenti non ho ancora la dimestichezza necessaria per crearlo da me, per cui ho semplicemente copiato il codice che ho trovato in un articolo sul vostro forum (vedi primo post) e inserito nelle mie pagine.
Il problema di questo codice è che non verifica i campi immessi appunto, quindi utenti vuoti possono inviare query vuote e registrarsi come vuoti.
La mia necessità è semplicemente di correggere questo problema, per il resto dei dati mi posso anche accontentare visto che il sito sarà visibile solo a persone già "selezionate". Tutto qua :)
 
ciao
due cose
sono io che ho detto di odiare la programmazione ad oggetti, poi i controlli devi metterli prima di fare la registrazione o l'accesso
esempio (così faccio io)
PHP:
<?php
//.....
if ($_SERVER["REQUEST_METHOD"] == "POST"){
	$errori="";//metto a vuoto una stringa
	//poi faccio i controlli
	if(trim($_POST['nome_utente'])){$errori="il nome utente non può essere vuoto<br / >";
	if(trim($_POST['password'])){$errori.="la password non può essere vuota<br / >";
	if(strlen($_POST['password'])< 3 || strlen($_POST['password'])> 8){$errori.="la password deve essere di almeno 3 e meno di 8 caratteri<br / >";}
	if(if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){$errori.="indirizzo email non corretto<br />";
	//se $errori non è vuota c'è un errore, lo mosto e rimando al form
	if($errori !=""){
		echo $errori;
		//e rimandi al form
		echo "<meta http-equiv='Refresh' content='3; URL=".htmlspecialchars($_SERVER['PHP_SELF'])."'>";
	}else{//$errori è vuota
		$registrato = $obj->registra(htmlentities($_POST['nome_reale'], ENT_QUOTES), htmlentities($_POST['nome_utente'], ENT_QUOTES), htmlentities($_POST['password'], ENT_QUOTES), htmlentities($_POST['email'], ENT_QUOTES));
		# controllo sull'esito del metodo
		if ($registrato) {
			# notifica in caso di esito positivo
			echo 'Registrazione conclusa <a href="index.php">ora puoi loggarti</a>.';
		}else{
			# notifica in caso di esito negativo
		}
	}
}
?>

non ho risposto subito perche sono mezzo in ferie
 
Immaginavo avessi da fare, comunque quello che hai scritto è chiaro ed è proprio quello che mi serve appena ho un po di tempo lo metto a punto e lo inserisco nel mio sito. Grazie
 
A prescindere che io uso un sistema di autenticazione molto complesso e molto sicuro ( almeno spero ) ti consiglio di iniziare a studiarti le nuove possibilità che il PHP offre dalle ultime versioni.
Comunque:
Come proposto da Borgo farei il trim sul post, ma non elemento per elemento ma tutto assieme
PHP:
function trimValue(&$value) {
	if (!is_array($value)) $value = trim($value);  
}	//	trimValue()

if (filter_has_var(INPUT_POST, 'entra') && filter_has_var(INPUT_POST, 'entra') != 'LOGIN') {
		array_filter($_POST, 'trimValue');	//	Tutti i dati in POST vengono passati alla funzione di trimming
}
così in un colpo solo ti levi il dente, inoltre ho fatto pure due cose: ho eliminata la scelta REQUEST_METHOD che penso sia inutile, dato che il form di invio lo scegli tu, quindi a che serve inserire una selezione sul metodo?
Altro ho usato un filtro che pone invece un sistema di controllo sui dati migliore, tieni presente che i filtri comunque usano le regex al loro interno, ma le "condensano" in un'unica istruzione.
In pratica verifico prima che il tasto "entra" ( l'ho immaginato io così, non so come hai messo tu, quindi correggi ) sia stato premuto e poi, che lo stesso tasto riporti l'esatto nome del suo value ( in questo caso ho immaginato la scritta LOGIN ) in questo modo puoi fare due cose:
  1. Verificare che nessuno ha modificato l'html prima di inviare il post ( si può fare credimi )
  2. Poter inserire più tasti di invio nello stesso form, creando una sorta di switching tra i vari elementi del form con la possibilità in inserire invii selettivi.
Ma torniamo al codicillo in oggetto :)
Borgo tenta di verificare un'email in questo modo:
PHP:
if(if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){$errori.="indirizzo email non corretto<br />";
in raltà sul manuale è inserito un codice più preciso che si può concretizzare in una funzione:
PHP:
function verificaEmail($email) {
    $sanitized = filter_var($email, FILTER_SANITIZE_EMAIL);
    $r = false;
    if ($valida = filter_var($sanitized, FILTER_VALIDATE_EMAIL)) {
        $r = $valida;
    }
return $r;
}

if (!verificaEmail($_POST['email'])) $errori = 'Indirizzo email non valido!';
In pratica i filtri funzionano così: per prima cosa viene sanificato l'indirizzo passato alla funzione, cioè viene pulito da caratteri spuri che con un indirizzo email non centrano nulla ( ad esempio < o > ) poi ne viene verificata la validità e se passa il controllo ti riporta l'indirizzo se no false!

Quindi la tua procedura di verifica e controllo potrebbe diventare così:
PHP:
function trimValue(&$value) { 
    if (!is_array($value)) $value = trim($value);   
}
function verificaEmail($email) { 
    $sanitized = filter_var($email, FILTER_SANITIZE_EMAIL); 
    $r = false; 
    if ($valida = filter_var($sanitized, FILTER_VALIDATE_EMAIL)) { 
        $r = $valida; 
    } 
return $r; 
}

if (filter_has_var(INPUT_POST, 'entra') && filter_has_var(INPUT_POST, 'entra') != 'LOGIN') { 
    array_filter($_POST, 'trimValue');    //    Tutti i dati in POST vengono passati alla funzione di trimming
	$options = array (
		'nick'	=>	array('filter' => FILTER_SANITIZE_STRING,
				  'flags' => array('FILTER_FLAG_STRIP_LOW', 'FILTER_FLAG_STRIP_HIGH')),
		'email'	=>	array ('filter' => FILTER_CALLBACK, 'options' => 'verificaEmail'),
		'p'		=>	array('filter' => FILTER_SANITIZE_STRING,
				  'flags' => array('FILTER_FLAG_STRIP_LOW', 'FILTER_FLAG_STRIP_HIGH'))
	);
	$risposta = filter_var_array($post, $options);
	$errori = false;
	if ($risposta['nick'] !== '' && $risposta['p'] !== '' && $risposta['email'] &== '') {
		if (!$risposta['email']) $errori = 'Si è verificato un errore nei dati inseriti, cortesemente verifica l\'esattezza del nome account o dell\'indirizzo email';
	} else {
		$errori = 'Si è verificato un errore nei dati inseriti, cortesemente verifica l\'esattezza del nome account o dell\'indirizzo email';
	}
	//	Tutto a posto posso continuare
	if ($risposta == false) {
		.... verifica e controllo nel database ....
	} else {
		echo $errori;
	}
}
Nota che ho scritto nel messaggio di errore: Si è verificato un errore nei dati inseriti, cortesemente verifica l'esattezza del nome account o dell'indirizzo email perché è sempre meglio non dire cosa hai sbagliato in un modulo di login per evitare di dare informazioni ad un possibile attaccante, ad esempio se mi dici che l'account è sbagliato posso immaginare che ci ho preso con l'email e viceversa.
Insomma buon divertimento e buon Natale :D

Ah, quasi dimenticavo di spiegarti il modulo di controllo!
Ho usato i filtri anche per verificare i dati in ingresso, in pratica ho creato un array in cui verifico la correttezza del nick name, che deve avere i caratteri compresi tra ASCII 32 e ASCII 122 se non ricordo male, insomma tutti i caratteri tra lo spazio e numeri, lettere maiuscole e minuscole, ma non le accentate!
Trovi molte e utili indicazioni qui: http://www.phpro.org/tutorials/Filtering-Data-with-PHP.html
Poi ho usata una funzione di callback per verificare l'indirizzo email e un sistema analogo al nick name per la password che ho chiamata P.
Quindi: una volta entrato nel selettore, fatta lo stripping dell'array POST, ho preso i dati e se questi ( tutti ) non sono a blank ( cioè vuoti ) verifico che l'email non sia negativa, se no è errore!
Insomma se tutto va bene il flag $errori rimane a false e se è così passo a verificare la correttezza dei dati inseriti, se no mando un messaggio di errore!
Semplice? No affatto :)

PS: anche se in parte ho fatto un copia e incolla tra il mio modulo standard e quello che ha scritto borgo, non l'ho provato quindi... provalo!
 

Discussioni simili