2010-07-13 25 views
5

Cuando un usuario se suscribe a mi boletín a través de su dirección de correo electrónico, utilizando php, ¿cómo podría enviar un 'Enlace de activación' por correo electrónico para confirmar que es su dirección de correo electrónico y no una falsa.enlace de validación por correo electrónico

por lo que en este momento no tengo

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>"; 
    } 
?> 

supongo que cambiaría el cuerpo $ a esto:

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

¿cómo iba a hacerlo de modo que si una Si el usuario hizo clic en ese enlace, agregaría sus datos a la base de datos Mysql, reconociendo que es un suscriptor legítimo.

Cualquier ayuda o sugerencia apreciada. Gracias

+0

posible duplicado de [Generar código de confirmación para una confirmación por correo electrónico] (http://stackoverflow.com/questions/2088969/generating-confirmation-code-for-an-email-confirmation) – Gordon

+1

@ Gordon: no es una pregunta duplicada, solo pregunta sobre la generación de números aleatorios. Este preguntó acerca de todo el procedimiento desde un nivel superior. – Borealid

+0

@Borealid yes dup. El cuerpo de la pregunta y las respuestas combinadas contienen todo lo que hay que saber para responder esta pregunta aquí. – Gordon

Respuesta

11

Lo que me gusta hacer es:

  • generar un identificador único, al azar en el proceso de registro

  • almacenar el ID junto con la dirección de correo electrónico, un "confirmada" sobre el terreno (predeterminado: "no") y cualquier dato adicional en una tabla de base

  • enviar el correo electrónico con una dirección URL que apunta a activar el identificador único (por ejemplo domain.com/activate.php?id=102939505595

  • La página de activación comprueba si la clave única existe y cambia el campo confirmed a yes (o 1 o lo que sea).

  • Además y opcionalmente, guarde la fecha/hora de confirmación, la dirección IP y el agente de usuario.

+0

pekka eres impresionante;) UP esa es la defination real. –

6

Inserte el usuario en una tabla con un conjunto de banderas 'pendientes' (o un indicador 'validado' no configurado). No deberían poder hacer nada hasta que se cambie la bandera. Si quieres ser realmente exhaustivo, póngalos en una tabla users_temp. Genere una clave totalmente aleatoria y asóciela con su ID de usuario. El enlace que les envíe por correo electrónico debe ser http://yourwebsite.com/?activate=totallyrandomkeyigeneratedearlier. Cuando reciba una solicitud de activación, active el indicador válido para el usuario con la clave aleatoria correspondiente.

+2

En caso de que envíe correos electrónicos cuando la cuenta se haya activado, considere eliminar la identificación después de la activación o verificar si se activó previamente. Tenía un sistema donde llamar al enlace de activación siempre activaría un correo electrónico y un usuario tenía la URL abierta en una pestaña del navegador durante días. Cada vez que reiniciaba su navegador y las pestañas se restauraban, obtenía una nueva confirmación de activación. – Gordon

1

Personalmente añadiría hay datos a la base de datos y tener unos campos llamados "activa" a continuación, cuando se haga clic en el enlace de activación de todo lo que tiene que hacer es actualizar éste campo.

También podría tener un enlace "Este no era yo" en el correo electrónico y si hacen clic aquí se eliminan todos los detalles.

+0

idea interesante sobre esto no era yo – RSM

1

Genere una ID única y almacénela junto con el nombre de usuario/contraseña dentro de una entrada de base de datos temporal para el nuevo usuario.

$tmpID = uniqid(); 

Entonces, adaptar el enlace en ti de correo electrónico cuerpo para por ejemplo:

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

Si el usuario solicita/activateAccount en su servidor, compruebe la entrada de la base de datos con el parámetro $_GET['activate'], y establecer el usuario activado (si coincide).

Para asegurarse de que su base de datos no solo obtenga más y más entradas, podría usar un cron-job que borre las entradas anteriores a, p. Ej. 24h.

+0

Esto puede estar abierto al ataque, ya que uniqid() es predecible. Asegúrese de utilizar al menos la bandera more_entropy. –

+0

Acepto, la bandera * more_entropy * lo hace más seguro. ¡Pero de todos modos, si no tiene acceso directo al servidor, será bastante difícil determinar la hora exacta! (¡Ya que uniquid() se basa en los microsegundos de la hora actual!). Por lo tanto, si no es posible el acceso directo, el atacante debe probar muchas teclas para encontrar el correcto. Por lo tanto, una limitación del número de ensayos de activación permitidos para la cuenta probablemente sería suficiente para evitar un ataque, y en general debería considerarse como una buena práctica. – Javaguru

1

En primer lugar se tendrá que añadir 2 columna a la tabla de base de datos que contiene los usuarios

La columna debe ser llamado active y activation_hash

Cuando el usuario se registra, tiene que insertar el usuario a la base de datos, pero establezca el active en 0 y el activation_hash se convierte en un md5 aleatorio de los usuarios email_address, first_name etc con un unique_id() allí, asegúrese de que esté en Formato MD5 y luego guárdelo en la columna activation_hash.

En su plantilla de email añadir el enlace para el usuario para activar tales como:

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

A continuación, dentro de su archivo de registro o donde quiera que su señalando el enlace de activación que, acaba de obtener el user_id & la activación hash a través de $_GET y valide contra su db.

si no coinciden, solicite al usuario que ingrese su contraseña para enviar otro hash de activación. de lo contrario, configure la columna active en 1 para que el resto de su aplicación sepa el estado del usuario.

eso es básicamente eso.

+0

Debe hash contra un valor aleatorio simplemente con una identificación única. Si el enlace incluye la identificación del usuario, no necesita que sea única, y el hash MD5 garantiza que no es único de todos modos. Sería mejor hacer hash contra un valor aleatorio, o simplemente usar un valor aleatorio sin el hash. –

+0

fue dirigido a mi publicación o simplemente era información adicional; si es así, expliqué que el archivo debería consistir en una matriz de datos que son exclusivos para ese usuario, así como algunos uniqe_id(); – RobertPitt

+0

es importante señalar la diferencia entre único y aleatorio. Una clave aleatoria de longitud suficiente sería preferible a una única. –

5

no se necesita base de datos. puede enviar todos los datos en el hipervínculo firmado por hash

He respondido una pregunta similar recientemente incluso con tiempo de caducidad.
pesar de que era para el enlace de recuperación de contraseña, pero la idea es la misma

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

símbolo conjunto se ve como número hexdecimal sola y sería difícil de adivinar su significado.

al recibir solo se divide y decodifica de nuevo.
Neat, IMO.

+0

Aún necesitará almacenar si el usuario está activado o no. Sin embargo, como se señaló, no es necesario almacenar un hash. –

+0

@Marcus puede crear una cuenta de usuario en el momento en que se activa. eso es todo –

+0

Esa es una idea clara, y definitivamente bajo mantenimiento. La implicación es que el hash está completamente basado en los datos proporcionados por el usuario, por lo que tendría que ser hash contra alguna clave secreta para evitar el abuso, o, como dijiste firmado, entonces tal vez algún algoritmo asimétrico. –

0

Aquí es mi completa escenario solución:

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

Añadir página de registro signup.php

Añadir la siguiente forma:

<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> 

Crear process.php página:

<?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(); 
    } 

?> 

después crear 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'; 
    } 

?> 
Cuestiones relacionadas