Nephtys
Nephtys

Reputation: 56

Joomla 3 authentication to get access to external app in PHP

I've found this very useful script to check the authentication in Joomla.

Joomla 3 External authentication script

<?php
/**
 * Joomla! External authentication script
 *
 * @author vdespa
 * Version 1.0
 *
 * Code adapted from /index.php
 *
 * @package    Joomla.Site
 *
 * @copyright  Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */
if (version_compare(PHP_VERSION, '5.3.1', '<'))
{
    die('Your host needs to use PHP 5.3.1 or higher to run this version of Joomla!');
}
/**
 * Constant that is checked in included files to prevent direct access.
 * define() is used in the installation folder rather than "const" to not error for PHP 5.2 and lower
 */
define('_JEXEC', 1);
if (file_exists(__DIR__ . '/defines.php'))
{
    include_once __DIR__ . '/defines.php';
}
if (!defined('_JDEFINES'))
{
    define('JPATH_BASE', __DIR__);
    require_once JPATH_BASE . '/includes/defines.php';
}
require_once JPATH_BASE . '/includes/framework.php';
// Instantiate the application.
$app = JFactory::getApplication('site');
// JFactory
require_once (JPATH_BASE .'/libraries/joomla/factory.php');
// Hardcoded for now
$credentials['username'] = 'adam';
$credentials['password'] = 'adam';
/**
 * Code adapted from plugins/authentication/joomla/joomla.php
 *
 * @package     Joomla.Plugin
 * @subpackage  Authentication.joomla
 *
 * @copyright   Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
// Get a database object
$db    = JFactory::getDbo();
$query = $db->getQuery(true)
    ->select('id, password')
    ->from('#__users')
    ->where('username=' . $db->quote($credentials['username']));
$db->setQuery($query);
$result = $db->loadObject();
if ($result)
{
    $match = JUserHelper::verifyPassword($credentials['password'], $result->password, $result->id);
    if ($match === true)
    {
        // Bring this in line with the rest of the system
        $user = JUser::getInstance($result->id);
        echo 'Joomla! Authentication was successful!';
    }
    else
    {
        // Invalid password
        // Prmitive error handling
        die('Invalid password');
    }
} else {
    // Invalid user
    // Prmitive error handling
    die('Cound not find user in the database');
}
?>

I'd like to use this to get the user authentication on my joomla website (domain_name/index.php) to an app in PHP I'm coding (domain_name/app/index.php) It works perfectly, but the harcoded part is a problem and I don't know how to dynamically get these variables depending on the user:

// Hardcoded for now
$credentials['username'] = 'adam';
$credentials['password'] = 'adam';

Does anyone have a hint or solution on how I can do this? Thank you in advance!

Upvotes: 2

Views: 1277

Answers (2)

Nephtys
Nephtys

Reputation: 56

Finally I could get what I wanted. I kept the first half of the script :

<?php
/**
 * Joomla! External authentication script
 *
 * @author vdespa
 * Version 1.0
 *
 * Code adapted from /index.php
 *
 * @package    Joomla.Site
 *
 * @copyright  Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */
if (version_compare(PHP_VERSION, '5.3.1', '<'))
{
    die('Your host needs to use PHP 5.3.1 or higher to run this version of Joomla!');
}
/**
 * Constant that is checked in included files to prevent direct access.
 * define() is used in the installation folder rather than "const" to not error for PHP 5.2 and lower
 */
define('_JEXEC', 1);
if (file_exists(__DIR__ . '/defines.php'))
{
    include_once __DIR__ . '/defines.php';
}
if (!defined('_JDEFINES'))
{
    define('JPATH_BASE', __DIR__);
    require_once JPATH_BASE . '/includes/defines.php';
}
require_once JPATH_BASE . '/includes/framework.php';
// Instantiate the application.
$app = JFactory::getApplication('site');
?>

and recover the user ID JFactory::getUser()->id in my app. Then I just had to create my variables from this ID $_userID = JFactory::getUser()->id.

Upvotes: 1

n9iels
n9iels

Reputation: 895

There are a lot of ways to do that! :-) For example you can create a class with this code and use a method to call it with parameters for the hardcoded user information.

However I think there is a better way to do this. You don't need to load the whole Joomla! framework to verify a username and password. Joomla! uses the default PHP functions password_hash and password_verify. What you can do is:

  1. Collect the user information of a login form using $_POST or so
  2. Perform a select query to the Joomla! users table to get the username and the corresponderen password. Eg. SELECT username, password FROM #__users WHERE username = '...'
  3. Verify the received password password_verify($_POST['password'], $data['password']). If it is correct, the user is logged in successful, if not return a message.

See for more information:

Another thing you might want to ask yourself is: do I really need a separated application that uses the same credentials as Joomla!. If the application is something you can integrate in Joomla! you can also create your own component. In some cases this is better.

Edit: one important note I forgot. This will only works if that passwords are generated with passsword_hash. So if the site cannot use this because of a old PHP version (update your stuff!!!), a md5 and salt is used as fallback. In that case password_verify won't work.

Upvotes: 1

Related Questions