2010-07-13 6 views
5

Quando un utente si iscrive alla mia newsletter tramite il loro indirizzo e-mail, utilizzando php, come potrei inviare loro un "Link di attivazione" via e-mail per confermare che è il loro indirizzo e-mail e non falso.collegamento di convalida via e-mail

quindi al momento ho

PHP:

<?php 
$to = "[email protected]"; 
$subject = "Hi!"; 
$body = "Hi,\n\nHow are you?"; 
if (mail($to, $subject, $body)) { 
    echo "<p>Message successfully sent!</p>"; 
    } else { 
    echo "<p>Message delivery failed...</p>"; 
    } 
?> 

Credo che vorrei cambiare il $ corpo a questo:

$body = "Please click the link to activate your email \n 
http://www.activationlink.com?"; 

Come dovrei fare in modo che se un l'utente ha fatto clic sul collegamento che aggiungerebbe i propri dettagli al database Mysql riconoscendo che sono un utente legittimo?

Qualsiasi aiuto o suggerimento apprezzato. Grazie

+0

possibile duplicato del [Generazione di codice di conferma per una mail di conferma] (http://stackoverflow.com/questions/2088969/generating-confirmation-code-for-an-email-confirmation) – Gordon

+1

@ Gordon: non una domanda duplice, collegata chiede solo di generare numeri casuali. Questo ha chiesto dell'intera procedura da un livello superiore. – Borealid

+0

@Borealid yes dup. Il corpo della domanda e le risposte combinate contengono tutto ciò che c'è da sapere per rispondere a questa domanda qui. – Gordon

risposta

11

Quello che mi piace fare è:

  • generare un unico, ID casuale nel processo di registrazione

  • memorizzare l'ID insieme con l'indirizzo di posta elettronica, un "confermato" campo (default: "no") e tutti i dati aggiuntivi in ​​una tabella di database

  • inviare l'e-mail con un URL che punta ad attivare l'ID univoco (ad esempio domain.com/activate.php?id=102939505595

  • La pagina di attivazione controlla se esiste una chiave univoca e modifica il campo confirmed in yes (o 1 o qualsiasi altra cosa).

  • Inoltre e, facoltativamente, salvare la data/ora di conferma, l'indirizzo IP e il programma utente.

+0

pekka you are Awesome;) UP questa è la vera definizione. –

6

Inserire l'utente in una tabella con un flag "in sospeso" (o una flag "validata" non impostata). Non dovrebbero essere in grado di fare nulla finché la bandiera non viene cambiata. Se vuoi essere veramente accurato, in realtà li metti in una tabella users_temp. Genera una chiave totalmente casuale e associalo con il loro ID utente. Il link che invii a loro deve essere http://yourwebsite.com/?activate=totallyrandomkeyigeneratedearlier. Quando ricevi una richiesta di attivazione, attiva il flag valido per l'utente con la chiave casuale corrispondente.

+2

Nel caso in cui si invii e-mail quando l'account è stato attivato, prendere in considerazione l'eliminazione dell'ID dopo l'attivazione o controllare se è stato precedentemente attivato. Avevo un sistema in cui chiamare il collegamento di attivazione avrebbe sempre attivato un messaggio di posta elettronica e un utente ha avuto l'URL aperto in una scheda del browser per giorni. Ogni volta che riavviava il browser e le schede venivano ripristinate, riceveva una nuova conferma di attivazione. – Gordon

1

Personalmente vorrei aggiungere lì dettagli per il database e hanno un campo chiamato "attivo" poi, quando si fa clic sul link di attivazione tutto quello che dovete fare è aggiornare questo campo.

Si potrebbe anche avere un collegamento "Questo non sono io" nell'e-mail e se si fa clic su questo si rimuovono tutti i dettagli.

+0

l'idea interessante di questo non ero io – RSM

1

Generare un ID univoco e archiviarlo insieme al nome utente/password all'interno di una voce di database temporanea per il nuovo utente.

$tmpID = uniqid(); 

Poi, adattare il link nella email-corpo per esempio:

$body = "Please click the link to activate your email \n 
http://www.activationlink.com/activateAccount?activate=".$tmpID; 

Se l'utente richiede/activateAccount sul server, controllare la voce del database con il parametro $_GET['activate'], e impostare l'utente attivato (se corrisponde).

Per assicurarsi che il proprio database non ottenga solo più voci, è possibile utilizzare un cron-job che cancella le voci precedenti ad es. 24h.

+0

Questo può essere aperto all'attacco, dal momento che uniqid() è prevedibile. Assicurati di utilizzare almeno la bandiera more_entropy. –

+0

Sono d'accordo, il flag * more_entropy * lo rende più sicuro. Ma comunque, se non si ha accesso diretto al server, sarà piuttosto difficile determinare l'ora esatta! (Poiché uniquid() si basa sui microsecondi del tempo corrente !!). Quindi, se non è possibile l'accesso diretto, l'attaccante deve provare un sacco di chiavi per trovare quello corretto. Pertanto, una limitazione del numero di prove di attivazione consentite per l'account sarebbe probabilmente sufficiente per prevenire un attacco e dovrebbe generalmente essere considerata una buona pratica. – Javaguru

1

In primo luogo è necessario aggiungere 2 colonna alla vostra tabella di database che contiene gli utenti

La colonna dovrebbe essere chiamato active e activation_hash

Quando l'utente registra è necessario inserire l'utente al DB, ma impostare active su 0 e lo activation_hash diventa un md5 casuale degli utenti indirizzo_email, first_name ecc. con uno unique_id(), assicurarsi che sia in formato MD5 e archiviarlo nella colonna activation_hash.

Nel modello e-mail aggiungere il link per l'utente di attivare come ad esempio:

<a href="http://mydomain.registrer.php?process=activate&id=<?php echo $user_id;?>&hash=<?php echo $activation_hash;?>">Activate your account</a>

poi dentro il file registro o dovunque voi la vostra puntando il link di attivazione per, solo ottenere l'user_id & l'attivazione hash via $_GET e validare contro il tuo db.

se non corrispondono, chiedere all'utente di immettere la propria password per inviare un altro hash di attivazione. in caso contrario, impostare la colonna active su 1 in modo che il resto dell'applicazione sappia quale sia lo stato dell'utente.

questo è fondamentalmente esso.

+0

Dovresti eseguire l'hash di un valore casuale piuttosto che un ID univoco. Se il link include l'id utente, non è necessario che sia univoco e l'hash MD5 garantisce che non sia comunque univoco. Sarebbe meglio hash contro un valore casuale, o semplicemente utilizzare un valore casuale senza l'hash. –

+0

era mirato al mio post o si trattava solo di informazioni extra, in tal caso ho spiegato che l'has dovrebbe consistere in una serie di dati che sono unici per quell'utente così come alcuni uniqe_id(); – RobertPitt

+0

è importante sottolineare la differenza tra unico e casuale. Una chiave casuale di lunghezza sufficiente sarebbe preferibile a una chiave univoca. –

5

nessun database necessario. è possibile inviare tutti i dati nel collegamento ipertestuale firmato dall'hash

Ho risposto a una domanda simile di recente anche con scadenza.
anche se era per il link recupero della password, ma l'idea è la stessa

$token = sha1($time.$email.$salt).dechex(time()).dechex($user_id); 
$link = "http://".$domain."/restorepass/?token=$token"; 

intero gettone sarebbe appare come numero unico esa decimale e sarebbe difficile da indovinare il suo significato.

al momento della ricezione, basta dividere e decodificarlo.
Neat, IMO.

+0

Avrai ancora bisogno di memorizzare se l'utente è attivato o meno. Tuttavia, come sottolineato, non è necessario memorizzare un hash. –

+0

@Marcus è possibile creare un account utente nel momento in cui viene attivato. questo è tutto –

+0

Questa è una buona idea e sicuramente poca manutenzione. L'implicazione è che l'hash è completamente basato sui dati forniti dall'utente, quindi dovrebbe essere sottoposto a hash contro una chiave segreta per evitare abusi o, come hai detto, forse un algoritmo asimmetrico. –

0

Ecco il mio pieno scenario di soluzione:

CREATE TABLE signup (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
username VARCHAR(30) NOT NULL, 
password VARCHAR(30) NOT NULL, 
email VARCHAR(30) NOT NULL, 
token VARCHAR(30) NOT NULL, 
verified VARCHAR(50), 
registration_date TIMESTAMP, 
maxdate TIMESTAMP 
); 

Signup MySQL Table

Aggiungi pagina di registrazione signup.php

Aggiungere il seguente modulo:

<form name="signupform" method="post" action="process.php"> 
    Username: 
    <input type="text" name="username"> 
    <br> Password: 
    <input type="text" name="password"> 
    <br> Email: 
    <input type="text" name="email"> 
    <br> 
    <input type="submit" value="Signup"> 
</form> 

Crea process.php pagina:

<?php 
$username = $_POST['username']; 
$email = $_POST['email']; 
$password = $_POST['password']; 
date_default_timezone_set('America/New_York'); 
$registration_date = date('Y-m-d H:i:s'); 
$verified = 0; 
$maxdate = date('Y-m-d H:i:s', strtotime($registration_date . ' +1 day')); 
$salt = uniqid(mt_rand() , true); 
$token = msha1(registration_date . md5($salt)); 
$sql = "INSERT INTO signup (username, password, email, token, verified, registration_date, maxdate) VALUES ('$username', '$password', '$email', '$token', '$verified', '$registration_date', '$maxdate')"; 

if (mysqli_query($conn, $sql)) 
    { 
    $msg = 'Please click this link to verify your email: http://www.yourdomain.com/verifyemail.php?token=' . $token; 
    mail($email, $subject, $msg); 
    } 
    else 
    { 
    echo mysql_error(); 
    } 

?> 

creare in seguito verifyemail.php:

<?php 
$token = $_REQUEST['token']; 
date_default_timezone_set('America/New_York'); 
$current_time = date('Y-m-d H:i:s'); 
$sql = "SELECT * FROM users WHERE token='$token' AND maxtime >'$current_time' AND verified=0"; 
$result = mysqli_query($conn, $sql); 
$notverified = mysqli_num_rows($result); 

if ($notverified) 
    { 
    $sql = "update signup set verified=1 where token='$token'"; 
    $result = mysqli_query($conn, $sql); 
    if ($result) 
     { 
     echo 'Email verified'; 
     } 
     else 
     { 
     echo 'Error'; 
     } 
    } 
    else 
    { 
    echo 'Link expired'; 
    } 

?> 
Problemi correlati