Easiest way for PHP email verification link

17,488

Solution 1

The easiest way is not to register unverified users at all.

Ask them for an email address and send email with a link that contains this address sealed with a hash. Upon receiving this link you can start the registration process.

Something like this

$secret = "35onoi2=-7#%g03kl";
$email = urlencode($_POST['email']);
$hash = MD5($_POST['email'].$secret);
$link = "http://example.com/register.php?email=$email&hash=$hash";

And in your register.php add 2 hidden fields to the registration form - email and hash, storing their received values from GET.

Finally, process registration and check,

if (md5($_POST['email'].$secret) == $_POST['hash']) {
    //Continue registration.
}

Solution 2

Easiest for whom - user, coder, computer? What are you optimizing - the quantity of keypresses, the size of the code, the user experience?

The easiest to code is probably unsafe. You should check the email address for correctness before sending a letter to it.

Share:
17,488
ryryan
Author by

ryryan

Updated on June 15, 2022

Comments

  • ryryan
    ryryan almost 2 years

    I already have an advanced user login/register system on my website (colemansystems.psm2.co.uk). However, I would like to have a email sent to new users for verification of their email address. If they have not clicked the link they will not be able to access their account. I am semi-experienced with PHP and MySQL, so please explain in depth.

    Edit: The code I'm using for the verify.php file (the link the user click on with a GET (for example, verify.php?d=51773199320))

    $secret = $_GET['d'];
    $result = mysql_query("SELECT valid FROM users WHERE secret=$secret");
    while ($row = mysql_fetch_array($result))
    {
        $valid = $row['valid'];
    }
    if ($valid == "") {
        echo"There seems to be a problem with the verification code.<br><br><br><br><br>";
    }
    elseif ($valid == "1")
    {
        echo"Your account is already verified.<br><br><br><br><br>";
    }
    else
    {
        mysql_query("UPDATE users SET valid = '1' WHERE secret=$secret");  
        echo "Thank you, your account is now verified and you are free to use the exclusive features!<br><br><br><br><br><br>";
    }
    

    Is this secure?

  • coolkid
    coolkid over 13 years
    this is a smart solution, you dont have to store the verificaton code in your database.
  • ryryan
    ryryan over 13 years
    I have taken your information on borad but made php generate a random code, this is then inserted into the database on the same row as the user + the valid field is set to 0 (to not allow them in). When they click on the link it then checks where the code is set to in the database and makes sure it isn't already valid and then sets valid to 1. This then allows them in. I'm not sure if it's secure though.
  • ryryan
    ryryan over 13 years
    Easiest for me, the coder. I want it to be easy and but very secure to stop hackers.
  • ryryan
    ryryan over 13 years
    This is the code i am using on the verify.php (the one that the user click with the secret at the end as a GET) at the top.
  • Grigori Kochanov
    Grigori Kochanov over 13 years
    Then you should use an existing proven and secure library. Like PHPMailer. Don't invent bicycles.
  • Drazen Bjelovuk
    Drazen Bjelovuk almost 7 years
    Kinda hinges on a risky single point of failure though, no? Anyone gets a hold of that secret can register under any email they like.
  • cazort
    cazort over 2 years
    I prefer a randomly-generated code stored in a database, to a hash. Hashes can be cracked, md5 in particular has been broken for years (2008, before your answer). It is easier to crack hashes used for email validation because an attacker can gather data by registering multiple accounts with different emails and seeing what hash is generated. If the attack succeeds, an attacker can validate accounts with fake emails. Randomly-generated codes are much more secure, but if you're gonna hash, at least use something stronger like sha256 or better.