Enable site authentication via email OR username

Remembering usernames and passwords for a million sites can be a tricky affair. Here at Joomlatools we are big fans of password managers. Not only can they generate super secure account details for you, there are available on all of your portable devices.

We can heartly recommend 1password as it has been battle tested by our team 1password.com

However encouraging your visitors to your site to make the leap to password managers might not be so easy. So why not make your site easier to login to? The default for Joomla is to login with a username and password, but what if a user hasn't visited for a while and can't remember their username?

What if you could let you users log in via email as well as username? Either or? The chances of your user's being able to login into your site has to be increased?

Please note for the purposes of this blog post, we are not trying to remove the username from the login process completely. This would require template overides, additional plugins and language string overrides. Not impossible, just a little out of scope for this tutorial about authentication plugins.

If you are interested in going this route, check out our Agency subscription which has full developer support including template overrides.

So we are going to have to create an authentication plugin, see the Joomla authentication plugin tutorial for further details.

Joomla has a series of authentication plugins, the default one is joomla. This will attempt to login you in via the traditional username and password route.

In keeping with the tutorial on authentication plugins, if PlgAuthenticationJoomla fails to provide a correct response the next authentication plugin is fired:

https://github.com/joomla/joomla-cms/blob/staging/plugins/authentication/joomla/joomla.php#L57-L71

Enter our new plgAuthenticationEmail:

<?php
// No direct access
defined('_JEXEC') or die;
jimport('joomla.plugin.plugin');
class plgAuthenticationEmail extends JPlugin {
    function onUserAuthenticate(&$credentials, $options, &$response)
    {
    }

So nothing to special there, we've simply created an authentication plugin that listens for login or authentication events.

    function onUserAuthenticate(&$credentials, $options, &$response)
    {
        $response->type = 'Joomla';
        if (empty($credentials['password']))
        {
            $response->status        = JAuthentication::STATUS_FAILURE;
            $response->error_message = JText::_('Sorry my friend going to need a password');
        }

So lets make sure that the user has provided an password or raise errors an error response.

$db = JFactory::getDbo();
$query = $db->getQuery(true)
    ->select('id, password, username')
    ->from('#__users')
    //switcha-roo sub username for email
    ->where('email=' . $db->quote($credentials['username']));
$db->setQuery($query);
$result = $db->loadObject();
if ($result) {
    $match = JUserHelper::verifyPassword($credentials['password'], $result->password, $result->id);

This is where the magic happens, you'll notice that the query to the database is set to check for a relevant email address based off the username provided. Notice the subtle switch there! Only if a suitable email in the #__users table record is found ($result) then we proceed to checking of the user's password.

All being good, the email address exists and the passwords match, then we can start creating our success response to the SiteApplication:

if ($match === true)
{
    $user = JUser::getInstance($result->id);
    $response->email = $user->email;
    //a correct username is still required for PlgUserJoomla::onUserLogin
    $response->username = $result->username;
    $response->fullname = $user->name;
    $response->language = $user->getParam('language');
    $response->status = JAuthentication::STATUS_SUCCESS;
    $response->error_message = '';
} else {
    // Invalid password
    $response->status = JAuthentication::STATUS_FAILURE;
    $response->error_message = JText::_('JGLOBAL_AUTH_INVALID_PASS');
}

Or if the passwords don't match we raise an error response to the wider SiteApplication process.

So hopefully that has piqued your interest into the world authentication plugins. If you did want to go fully into using emails instead of usernames for registrations, logins and reminders please do remember to check our Agency subscription.

Tell us your thoughts

If you have any more ideas or want to share your workflow with us, we love to hear from you! Get in touch through our developer channels on Twitter or Facebook.

Happy Joomla coding!