How to activate email

I have managed to send an email link to the user upon registration with their email and the token but how would the information be passed to my activation form? I think I would need to use the $_get method but how would I do this? The user has the following email…How would I match their token with the token in my database and their email?

http://localhost/loginsystem/includes/activate.php?email=piano0011@hotmail.com&activatetoken=RacqFHdHGT

You make a SELECT query using the email & token in the WHERE clause.

I understand that part but just don’t know how i could check the information from the url…

Yes, that’s correct. Have a look at the $_GET array. It’s very similar to the $_POST array that you’ve already used in other code.

1 Like

Simplified example, when the user registers to your site you save the user_id and token to db and send the activation link to the user’s email. Lets assume the link would be like https://your.site.com/activate_account.php?user_id=3&token=usersUniqueSecretToken. Now when the user receives your link and follows it to your activation page activate_account.php, two GET will be set on that script.

$_GET['user_id'] // contains value 3
$_GET['token']   // contains value usersUniqueSecretToken

You compare these GET values to the values set in the db at the time of the registration and if they match you set the user account as activated. Otherwise it stays not activated.

Since the token is unique, you don’t need to send the user_id as well :slight_smile:

Just make sure there is a UNIQUE constraint on that column in the database so you really don’t get any duplicates.

2 Likes

I can only get my activation to work with using token but i tried to make the token more secure by using password_hash and then password_verify but can’t get it to work with it… should we hash a token or just set an expiry date for the token?

Just set an expiry date. Hashing makes no sense here. Just create a long enough hash of say 40 characters or so.

For some reason, my database is not updating the 0 to 1 but I am receiving the email stating that it has been successfully activated…Also, what is the proper way to concatenate a string variable? Do I use ‘$name’ or ‘“.$name.”’

<?php


if (!isset($_GET['email']) || !isset($_GET['activatetoken'])) {
   header("Location: ../index.php?activate=missinglink");
   exit();
} else {

  include_once 'dbh.php';
  

  // retrieve the email and token from url

  $email = mysqli_real_escape_string($conn, $_GET['email']);
  $token = mysqli_real_escape_string($conn, $_GET['activatetoken']);
  




  // select information from the database and match it

  $sql = "SELECT user_email, user_token FROM users WHERE user_email = '$email' AND user_token = '$token' AND user_activate = 0";
  $result = mysqli_query($conn, $sql);
  $resultCheck = mysqli_num_rows($result);
  if($resultCheck > 0) {
    $sql = "UPDATE users
            SET user_activate = 1, user_token =''
            WHERE user_email = '$email'
            ";
   mysqli_query($conn, $sql);



  }

}

 $mailFrom = "PianoCourse101";
    $subject = "Thank you for activating your basic membership account!";
    $name = "PianoCourse101";
    $mailTo = "piano0011@hotmail.com";
    $headers = "From: ".$mailFrom;
    $txt = "Thank you for activating your free account! \n\n You can now access your free membership and watch the Bastien piano lessons all for free! If you enjoy your time with us, then feel free to purchase our Level 1, Level 2 and Level 3 course! \n\n At PianoCourse101, we are trying to make your piano learning experience enjoyable and convenient!\n\n Please visit the update profile section to check your details. It is important that the details are correct and if there are any incorrect information, please don't hesitate to email us.";

    mail($mailTo, $subject, $txt, $headers);
    header("Location: ../index.php?activate=sucess");
    exit();

// Send an email to confirm activation of account:

Well, you send the email regardless of whether $resultCheck is larger than 0 or not.

Also, you really do not need the email address in this check, just the token is enough. Get rid of the email address, which will also be in the server logs (since it’s part of the URL), etc. You don’t need it, you don’t want it.

Regarding string concatenation, there are several options, and it mostly boils down to opinion which one you use.

  1. Simple concatenation: 'foo ' . $somevalue . ' bar' - trivial and easy to follow

  2. String intepolation: “foo $somevalue bar” - requires double quotes, and is generally believed to be a tad slower than concatenation, though in the grand scheme of things this is probably negligable.

  3. sprintf: sprintf(‘foo %s bar’, $somevalue); - bit harder to grasp because you need to know that %s is for strings, %d is for integers etc, but extremely easy to read when you do, it’s much easier than the two above, especially for long strings with lots of variables.

However, what you’re doing with your queries should not by solved by string concatenation, but by using prepared queries, as multiple people have told you several times now.

// no longer use mysqli_real_escape_string, it's not safe
//$email = mysqli_real_escape_string($conn, $_GET['email']);
//$token = mysqli_real_escape_string($conn, $_GET['activatetoken']);

$sql = "SELECT user_email, user_token FROM users WHERE user_token = ? AND user_activate = 0";
$stmt = mysqli_prepare($conn, $sql);
mysqli_bind_param($stmt, 's', $_GET['activatetoken']);
mysqli_execute($stmt);
$resultCheck = mysqli_num_rows($stmt);

Using PDO instead of MySQLi would make for much nicer code though. Something to keep in mind.

1 Like

Can I add the following codes underneath the activation part? I tried to do this one the same page and my email activation was not reliable. However, if I put this on a separate page, then I think it is working…

$mailFrom = "PianoCourse101";
    $subject = "Thank you for activating your basic membership account!";
    $name = "PianoCourse101";
    $mailTo = "piano0011@hotmail.com";
    $headers = "From: ".$mailFrom;
    $txt = "Thank you for activating your free account! \n\n You can now access your free membership and watch the Bastien piano lessons all for free! If you enjoy your time with us, then feel free to purchase our Level 1, Level 2 and Level 3 course! \n\n At PianoCourse101, we are trying to make your piano learning experience enjoyable and convenient!\n\n Please visit the update profile section to check your details. It is important that the details are correct and if there are any incorrect information, please don't hesitate to email us.";

    mail($mailTo, $subject, $txt, $headers);
    header("Location: ../index.php?activate=sucess");
    exit();

I know that you did say to use phpmailer, I guess that is more reliable to get the code working but it seems tedious to change certain settings…

What happened when you tried?

How was it not reliable? What happened and what did you did expect should have happened instead?

That’s not a good idea because then every time someone refreshed the page they get another email.

1 Like

How about string concatenation and prepared queries though, any thoughts on that?

1 Like

Like when you finally get around to converting the whole application to something more modern and secure like you repeatedly say you intend to do one day, once you have spent an age creating a “working” but obsolete, insecure and unfit for purpose site?
Avoid tedium and time wasting, do it right first time. :wink:

4 Likes

True that.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.