Adding Security to Your Web Application with Two Factor Authentication with Drupal

Want to add more security to your web application? Try the two factor authentication and stay secure.




May 11, 2020


Barkan Saeed



With rising incidents of phishing attacks, account takeover, and data theft, web security is a key feature of any web application. Passwords aren’t sufficient enough to prevent hackers from accessing your information and stealing your identity. Extra security precautions need to be taken to ensure your online identity remains safe.

Many technology firms have started to implement a Two-factor authentication system in their web applications to ensure the safety of their user’s information.

A Two-factor authentication system adds an extra step before you log in to your account. The first step is to sign in with the username and password. After this is entered, it takes you to the second step, where the system asks you to provide another form of identification. This identification can be of many different types. Usually it is a physical token like an ATM card or it could also be a security code or a phone number.

TFA and SMS Gateways

In a two factor authentication, there are two layers of security. Usually there is email verification and then SMS verification. To add SMS verification, a SMS gateway needs to be integrated. There are many gateways available like Clickatell, Twillio, Tropo, etc.

Twillio is a popular SMS framework that can be integrated. It’s best for a simple application. Its drawback is that it doesn’t allow users to send more than 1000 SMS per second and since it’s a free account, messages can only be sent to verified numbers.

Drupal community has also contributed by writing modules for it. TFA is one module developed for two factor authentication. This module adds a second layer of security to the login process. It is a simple module which most applications have integrated in them because of its simplicity. SMS framework is another module developed by Drupalers. This module is considered to be the backbone of the TFA module and other similar modules.

Custom module setup and workflow

In one my projects, I had to add a second layer of security for the login and forgot password forms. The developed application enabled the user to save all his confidential information in one place so that it could be quickly accessed whenever needed. For this application, a Two Factor Authentication was a necessity to prevent identity theft.

Drupal’s TFA module was the best option to implement. However, the module addressed only the login form. Our requirement was for both the login and forgot password. We had to customize the module to meet our requirement.

Enhancing the Module

The following steps were carried out for developing a simple two factor authentication process for a form.

The first thing is to change the forgot password form validate and submit handlers. We are doing so because on submit in addition to email the sms code is also sent.

To change these handler drupal has a hook of form_alter($form_id) so we will start with this form_alter

Call hook_form_alter to alter drupal default forget password form

yourmodulename_form_alter   (  &$form,
&$form_state, $form_id      )    {
if($form_id == ‘user_pass’) { // This condition will only be true
for forgot password
//We unset form default validate function and set our own submit and validate handler
$form[‘#validate’][0] = ‘custom_user_pass_validate’;
$form[‘#submit’][0] = ‘custom_user_pass_submit’;

In submit handler, in addition to the default action i.e. (recovery email) also the code to the mobile is sent.

if     (   _send_verification_sms    (
)    )    {     //       If the sending sms
process successful watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail)); drupal_set_message(t('Further instructions have been sent to your e-mail address.Also a recovery code is sent via SMS to your mobile phone.'));


$form_state[‘redirect’] = ‘user’;
} else {
drupal_set_message(t(‘Sorry there is some error sending your message.), ‘status’, FALSE);
/* Function body for sending sms */
_send_verification_sms    (    )
{    require   (    'twilio
latest/Services/Twilio.php'       )        ;
// the twilio library should be included in order to send the sms
// Your Account Sid and Auth Token from $account = $_SESSION[‘account’]; // we store it in session because global user object can’t be accessible as the user is not logged on yet
$sid = variable_get(‘twilio_secret_code’);
$token = variable_get(‘twilio_auth_token’);
$from_phone_no = variable_get(‘phone_no’); // the phone number of account holder of twilio
$to_phone_no = $account->profile_phone_number; // the phone number to which the sms sent
$six_digit_random_number = mt_rand(100000, 999999);
// we are saving the code in session, however , It can be saved in database against user_id
$_SESSION[‘code’] = $six_digit_random_number; // stored the code for later verification
// Save the code in data base against user id
db_query(“INSERT into {sms_codes} id = %d, code=%s’”,$account->uid, $six_digit_random_number);
$client = new Services_Twilio($sid, $token);
$message = $client->account->sms_messages->create($from_phone_no, $to_phone_no, “Please enter the code..$six_digit_random_number, array());
if(isset($message)) {
return true;
} else {
return false;


The email format function is overrided and the text containing the email changed to the path of the code verification path.


sms_authentication_mail    (     $key, &$message,
$params   )             {          $language
$message       [    'language'   ]    ;
$variables    =
drupal_mail_tokens    (      $params    [
'account'    ]     ,
$language     )    ;
switch   (    $key    )
{     case
'password_reset'   :
$message      [    'subject'    ]
=   t    (     'Notification from
!site'    ,   $variables    ,
$language     -
>     language    )    ;


// This is the custom body which is changed to address the requirement the !uri_breif will contain the path of sms verification form instead of one time login screen which means a second layer.


$message[‘body’][] = t(!username,\n\nA request to reset the password for your account has been made at !site.\n\nYou may now log in to !uri_brief by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it’s not used.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password., $variables, $langcode);


Finally during sending code, the stored value of code is compared with the redirected from email path.
modulename_form_validate     (     &$form,$form_stat
e    )    {           //In case stored in session $code = $_SESSION['code']; // get the stored code $account = $_SESSION['account']; //In Case stored in database $code = db_result(db_query(‘select code from {sms_codes} where id = %d’,$account->uid)) if($code != $form_state [‘values’]['code']){ //compare the code form_set_error('error','The code you entered is not matched! Please try again!'); return false; }
return true;


If the code is okay it will get the user to the one time login screen.


modulename_form_submit    (    &$form,$form_stat
e     )     {     $account     =
$_SESSION     [      'account'    ]     ;
 $url    =
user_pass_reset_url     (    $account
;         //drupal core function that returns the url on time login screen
// Destroy Session and the database entry
db_query(delete from {sms_codes} where id = %d ’, $account->uid);

If the code is wrong, it will not let the user access the one-time login process.


Module Setup

For the above module to work, it is necessary to have a Twilio account. Once an account is created, an OAuth token is given along with the SSID and a phone number that will be used in the code. These should be saved for future reference.

Once the custom module is installed and enabled, log into the admin panel to change the settings. In the admin panel, navigate to admin/settings/sms_authentication and enter the credential which was provided by Twilio. You also need to have a valid phone number saved in your profile. Once the settings have been changed, run the module through the ‘forgot password form.


This module provides a good starting point for integrating SMS authentication in your websites. This is the first version of the module and will be extended in future.


Islamabad, Pakistan

Floor 2, Building 145, Civic Center Bahria Town Phase 4, Islamabad, Pakistan


1 squire armor road, windham, NH,03076

Saudi Arabia

7654 Prince Nawaf Street, Al Khobar, 34426

Kingdom Of Bahrain

No 851, Bldg No 2420, Rd No 2831, Seef District, Block 428