Nov 162014
 
Article HTML

A web site that is going to offer a customized service for registered users need to implement a signup and login procedure. Validated users can then be granted access to functionalities that could eventually make use of specific user data, not available for anonymous users.

This post explains a possible implementation of this signup and login procedure in PHP

1. Signup form

The signup form must request as a minimum the user identifier and password that will be needed later for the user to login to the service. It is quite common to also request an email address, and this email address is more and more used as the user identifier.

The signup form may request some additional information: age, gender, address,… Some of these data may be optional and some other mandatory, depending on the type of service offered by the web site.

For instance, the following HTML code generates a form requesting an email address and password, and gives the option to subscribe to a newsletter:

<form method="POST" action="/register.php" accept-charset="utf-8">
  <label for="signup_email">Email</label>
  <input type="text" name="signup_email" value="" id="signup_email" maxlength="255" size="30"  />
  <label for="signup_password">Password</label>
  <input type="password" name="signup_password" value="" id="signup_password" size="30"  />
  <label for="sconfirm_password">Confirm Password</label>
  <input type="password" name="confirm_password" value="" id="signup_confirm_password" size="30"  />
				  
  <input type="checkbox" name="signup_newsletter" value="subscribed" checked="checked" 
                         id="signup_newsletter" class="chk-signup" />
				 
  <label for="signup_newsletter" class="txt-signup">Keep me up to date with news, software updates,
					and the latest information on products and services.
  </label>
  <input type="submit" name="signup_submit" value="Sign Up" class="btn">
</form>

This HTML code, together with some CSS style, generates a form:

signup-form

 

2. Processing the signup form

When the “Sign Up” button is clicked, the content of the form is sent to the “register.php” script to be processed.

But before the form is sent to the server, in a production service it is common to add some kind of client-side validation (verify that the syntax of the email address is valid, the content of fields “Password” and “Confirm Pasword” match, the password has a minimum length, etc.). This validation is implemented by means of a javascript function attached to the “onsubmit” event that is triggered immediately before the form content is sent.

Nevertheless, it is advisable to perform again the validation on the server, as part of the process performed by the “register.php” script.

“register.php” can be implemented as follows:

    // Read form data
        ...

    // Perform validation
       ...


    // Insert user in the database
        ...

    // Send confirmation email
        ...

2.1. Reading the form data received

The sample signup form above specified method=”POST”. Therefore, the values of the form fields are made available to the PHP script as elements in the $_POST array:

// Read form data
$email = $_POST["signup_email"];
$password = $_POST["signup_password"];
$newsletter = $_POST["signup_newsletter"];

2.2. Performing validation of the input data

The most basic validation that can be done is testing that the password has a minimum length, and the confirmation password matches. It these tests fail, an appropiate message is printed:

// Perform validation
$error_message = ""
if (strlen($password) < 6) {
    $error_message = "Password too short. Please enter at least six characters";
} else if ( $password != $_POST["signup_confirm_password"]) {
    $error_message = "Password mismatch. Please try again";
}

Besides, it is a good partice to check that the syntax of the email address is correct. The standard PHP function filter_var can be used for this:

if ( ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $error_message = "Please verify the email address";
}

Note: filter_var() can also be used to check the validity of other field types, in case they are added to the form, using the appropriate flag: FILTER_VALIDATE_BOOLEAN, FILTER_VALIDATE_INT, FILTER_VALIDATE_IP, FILTER_VALIDATE_URL, etc. The list of available validation filter types can be consulted here

2.3. Inserting the user in the database

The list of registered users must be stored somewhere. In this guide we will assume that a table ‘users’ in a mysql database is used to keep this list.

The table ‘users’ has the following fields:

  • `email`  – email address. This field must be the primary key of the table, to avoid duplicates.
  • `password` – password
  • `newsletter` – set to true if the user wants to receive the newsletter
  • `registration_date` timestamp DEFAULT CURRENT_TIMESTAMP – signup date
  • `activation_key` – used to confirm the email address, as explained in 2.4.
  • `validated` – flag to indicate that the confirmation of the email address has succeeded

The registration procedure must check if the email address entered is already in the users table. If the `email` field is defined as the primary key of the `users`table, this can be done at the time the user record is inserted, because the insert will fail with a “duplicate key” error if the user existed:

// Insert user into database
$random_key = generate_random_key();
$stm = $dbh->prepare("insert into users (email,password,activation_key,validated) " .
                     "values ( ? , ? , ? , 0 )");
$stm->bind_param("sss",$email,$password,$random_key);
if (!$stm->execute()) {
    // The insertion may fail if the user already exists in the database
    $error_message = "Sorry, the user entered was already registered in our database";
} else {
    // Send a confirmation email
    ...
}

The function “generate_random_key()” generates a random, 32 characters long activation key. It  can be implemented as follows:

function generate_random_key() {
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";

    $new_key = "";
    for ($i = 0; $i < 32; $i++) {
        $new_key .= $chars[rand(0,35)];
    }
    return $new_key;
}

2.4. Sending a confirmation email

A confirmation email is sent to the email address entered, with a link that needs to be clicked to complete the signup process. A possible implementation of this can be done using the standard mail() function:

           // Send email to validate the email address entered
            mail($email,"example.com - Account activation ",
                "Welcome to example.com!
        
                Thank you for registering at our site.
                Your account is created and must be activated before you can use it.
                To activate the account click on the following link or copy-paste it in your browser:
                http://example.com/activate.php?activation=".$random_key);

When the user receives the email and clicks on the link, the script “activate.php” is executed on the server. The activation key is passed as the value of the argument “activation”.

The script activate.php justs toggles the flag “validate” in the users table, starts a session, and display a confirmation message:

    $activation_key = $_GET["activation"];
    $dbh = get_dbh();
    // Search the entry in the users table for the received activation key
    $stm = $dbh->prepare("select count(1) from users where activation_key=?");
    $stm->bind_param("s",$activation_key);
    $stm->bind_result($total);
    $message = "";
    $stm->execute();
    $stm->fetch();
    $stm->close();
    if ($total == 1) { // If found...
        // Retrieve the email address
        $stm = $dbh->prepare("select email from users where activation_key=?");
        $stm->bind_param("s",$activation_key);
        $stm->bind_result($email);
        $stm->execute();
        $stm->fetch();
        $stm->close();
        // Set the validated flag in the database
        $stm = $dbh->prepare("update users set validated=1 where activation_key=?");
        $stm->bind_param("s",$activation_key);
        $stm->execute();
        $stm->close();
        // Log the user into the session
        $_SESSION["user"] = $email;
        $message .= "Thank you for registering with us<br/><br/>" .
            "Welcome to example.com!<br/><br/>" .
            "<a href='http://example.com' class=\"btn\"'>Continue</a>";

And that completes the signup procedure

3. Login form

The login form could just have two fields “email” and “password” that are sent to a “login.php” script. It is also common to add a link to recover or reset the password if it has been forgotten. This HTML code generates a sample login form:

  <form method="POST" action="/login.php">
      <label class="email">Email</label>
      <input type="text" name="user">
      <label class="pww">Password</label>
      <input type="password" name="pass">
      <a href="/olvido.php" role="button" data-toggle="modal">¿Forgot your password?</a>
      <input type="submit" class="btn" name="login" value="login">
  </form>

With this code and some CSS style, the sample login form can look like this:

login-form

 

The “login.php” script must check that there is a matching entry in the users table for the email and password entered, and start a validated session:

//Validate user and password
$email = $_POST["user"];
$password = $_POST["pass"];

$stm = $dbh->prepare("select email from users where email=? and password=?");
$stm->bind_param("ss",$email,$password);
$stm->execute();
$login_error_message = "";
if ($stm->fetch()) {
    $_SESSION["user"] = $email;
    // Redirect user to the home page
    header( 'Location: http://example.com/' );
    return;
} else {
    // Display error message
        ...
}

References

 Posted by at 4:54 pm

 Leave a Reply

(required)

(required)