用于登录的Joomla插件

时间:2014-07-28 14:33:38

标签: php joomla

更新

@Elin:

感谢您的链接!对于糟糕的评论表示抱歉,我只是不打算使用换行符 但我尝试的并不是真正改变用户。我只是想创造它。 但是,我改变了我的插件应该做的计划。也许你知道如何使我的计划有效:
我探讨了以下内容:
如果我在Joomla DB中有一个用户名1,密码为1的用户和另一个密码的同一用户(这很重要,因为否则用户会直接在我的外部数据库中对Joomla DB进行身份验证),请使用密码登录前端外部DB工作没有任何问题。
登录后端只能使用Joomlas DB中的用户密码(以及其他人),即使所有细节都相同(即使是组)。

如何将针对外部数据库进行身份验证的用户登录到后端?!

还有一次非常感谢!

_____ 更新结束 ____

我有一个(希望)小问题让我发疯:

我juste为Joomla 3.1写了一个插件。此插件允许针对外部Web服务器脚本进行身份验证(使用onUserAuthenticate())。工作正常。

比我认为最好使后端访问成为可能。所以我写了第二个插件来实现这一点。 此插件搜索Joomlas DB中的授权用户,如果找不到 #__ users #__ user_usergroup_map ,则将其添加。到这里它也可以正常工作。

现在我的问题:

前端登录有效,后端没有(仅显示空白页)。 我是否还必须将用户插入任何其他表格?或者是否有任何遗漏?我忘记了什么吗?!

我的登录插件代码:

<?php
/**
 * @package     Joomla.Plugin
 * @subpackage  Authentication.External
 *
 * @copyright   Copyright (C) 2014 Stefan Herzog. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * External Authentication Plugin
 *
 * @package     Joomla.Plugin
 * @subpackage  Authentication.external
 * @since       3.1
 */

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
class PlgUserExternal extends JPlugin
{
    /**
     * Load the language file on instantiation. Note this is only available in Joomla 3.1 and higher.
     * If you want to support 3.0 series you must override the constructor
     *
     * @var    boolean
     * @since  3.1
     */
    protected $autoloadLanguage = true;
    /**
         * This method should handle any authentication and report back to the subject
         *
         * @param   array   $credentials  Array holding the user credentials
         * @param   array   $options      Array of extra options
         * @param   object  &$response    Authentication response object
         * @param   object  $response     Authentication response object
         * @param   array   $result       Authenticataion response array    
         * @return  boolean
         *
         * @since   1.5
         */
        public function onUserLogin($user, $options = array())
        {

            // Set default values
            $allow_backend_access = FALSE;  


            if(isset($user['admin']) AND $user['admin'] === 1)
            {
                $allow_backend_access = TRUE;     // works! This parameter is delievered with $response from onUserAuthentication()
            }

            // Get a db connection.
            $db = JFactory::getDbo();

            // Create a new query object.
            $query = $db->getQuery(true);

            // Select all records from the user profile table where key begins with "custom.".
            // Order it by the ordering field.
            $query->select($db->quoteName(array('id')));
            $query->from($db->quoteName('#__users'));
            $query->where($db->quoteName('username') . ' = '. $db->quote($user['username']));

            // Reset the query using our newly populated query object.
            $db->setQuery($query);

            // Load the results as a list of stdClass objects (see later for more options on retrieving data).
            $results = $db->loadAssoc();    

            if(count($results) == 0)
            {
                $checkUser = 0;
            }
            elseif(count($results) >= 1)
            {
                $checkUser = 1;
                $user_id = $results['id'];
            }

            if($checkUser === 0)
            {

                // Create a new query object.
                $query = $db->getQuery(true);

                // Insert columns.
                $columns = array('name', 'username','email','password');

                // Insert values.
                $values = array($db->quote($user['fullname']), $db->quote($user['username']),  $db->quote($user['email']), $db->quote($user['password']));

                // Prepare the insert query.
                $query
                    ->insert($db->quoteName('#__users'))
                    ->columns($db->quoteName($columns))
                    ->values(implode(',', $values));

                // Set the query using our newly populated query object and execute it.
                $db->setQuery($query);
                $db->query();
                $user_id = $db->insertid();

                if($user_id >> 0)
                {
                    /************* Insert user into user_usergroup_map table *************/

                    foreach($user['groups'] AS $group_id)
                    {
                        $columns    = NULL;
                        $values     = NULL;
                        $query = $db->getQuery(true);

                        // Insert columns.
                        $columns = array('user_id', 'group_id');

                        // Insert values.
                        $values = array($db->quote($user_id), $db->quote($group_id));

                        // Prepare the insert query.
                        $query
                            ->insert($db->quoteName('#__user_usergroup_map'))
                            ->columns($db->quoteName($columns))
                            ->values(implode(',', $values));

                        // Set the query using our newly populated query object and execute it.
                        $db->setQuery($query);
                        $db->query();
                    }
                //$instance = $this->_getUser($user, $options);
                }
            }

            // $instance = JFactory::getUser($user_id); // works
        }
    }?>

感谢您的帮助!

祝你好运 斯蒂芬

2 个答案:

答案 0 :(得分:0)

这些非常复杂,哈哈。提出一些指导的几点想法。

首先,您应该只需要一个身份验证插件来处理前端和后端身份验证。在身份验证插件中,您可以使用以下命令识别请求是来自前端还是后端登录表单:

JFactory::getApplication()->isSite();

JFactory::getApplication()->isAdmin();

其次,我不确定你是否从你的帖子中做到这一点,但是当新的站点访问者对你的外部数据库进行身份验证时,无论他们是否在前面进行身份验证,你都应该始终在数据库中创建一个Joomla用户或后端。

第三,在创建用户时,我建议让Joomla核心通过使用JUser对象创建新用户来完成所有工作。例如,您可以创建并保存用户:

$user = new JUser();
$user->set('name', $columns['name']);
$user->set('username', $columns['username']);
$user->set('email', $columns['email']);
$user->set('password', $columns['password']);
$user->save();

现在这当然非常简化,没有任何数据验证或清理,因此您必须努力在代码中执行这些检查。

编辑1

正如op指出的那样,我没有提供有关这些团体的任何反馈。如果您知道组ID,则可以使用用户帮助程序类添加它。执行save:

后,您应该在JUser对象中拥有新的用户ID
JUserHelper::addUserToGroup($user->id, $group_id);
祝你好运!

答案 1 :(得分:0)

Joomla后端具有一定的内置安全功能,这使得登录后端基本上更加困难。例如,如果您曾尝试针对后端发出REST请求,则会出现白屏。如果你在后端查看com_login,你会发现它与com_users的登录视图完全不同。您需要基本上强制使用创建过程(可能对用户不可见)来完成前端。要允许管理员访问您要执行的操作,请创建具有login.admin权限的默认用户组。您可以在插件中覆盖该配置设置。

如上所述,您应该只使用Joomla API来创建用户,因为它很复杂,涉及许多表,您需要正确处理加密。您可能需要用户插件以及身份验证插件。您可能想要了解Cookie身份验证在Joomla中的工作方式,尽管它在后端被特别阻止。

更新

我不明白您是在尝试更改现有用户。如果查看JUser代码,您将看到更改用户需要与具有更改用户权限的用户进行会话。您拥有的会话是一个用户的会话(因为她的组尚未更改)肯定没有用户编辑权限。进一步添加会话需要属于超级管理员的超级管理员。问题是你没有会话。有一种方法可以假装我使用here。由于您实际上知道管理员用户的ID,因此您甚至可以对其进行硬编码。

更新2

由于我提到的(与REST相同的问题),您将不得不面临挑战。基本上,两个应用程序中的授权和认证流程是不同的。在后端你必须通过登录,所以你的插件真的需要模拟登录过程。请注意它在JApplicationAdmin中是如何硬编码的。有一些插件可以为管理员实现基本身份验证,这是另一种可能性,但只有当你在我看来使用ssl时,除非你在100%的防火墙后面。 Com_config执行一个可能有用的共享会话。