繁体   English   中英

用于登录的Joomla插件

[英]Joomla plugin for login

更新:

@Elin:

感谢您的链接! 非常抱歉,我的评论格式如此糟糕,我只是不让换行符起作用。
但是我尝试的并不是真正地改变用户。 我只是想创建它。 但是,我更改了插件应做的计划。 也许您有一个想法使我的计划生效:
我探索了以下内容:
如果在我的外部DB中,我有一个用户名1的用户,其密码为1,而在Joomla DB中该用户的密码为1(这很重要,因为否则该用户将直接针对Joomla DB进行身份验证),请在前端登录,并使用来自外部数据库工作正常。
即使所有详细信息都是相同的(甚至是组),登录后端也只能使用Joomlas DB中的用户密码(依此类推)。

如何将通过我的外部数据库进行身份验证的用户登录到后端?

多谢一次,谢谢!

_____更新结束____

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

我只是为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
        }
    }?>

多谢您的协助!

最好的问候斯特凡

这很累,大声笑。 提供了一些思路以提供一些指导。

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

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

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

其次,我不确定您是否从您的帖子中进行此操作,但是当新的网站访问者针对您的外部数据库进行身份验证时,无论他们在前端还是后端进行身份验证,都应该始终在数据库中创建Joomla用户结束。

第三,在创建用户时,我建议让Joomla core通过使用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,则可以使用用户帮助程序类添加它。 执行保存后,您应该在JUser对象中具有新的用户ID:

JUserHelper::addUserToGroup($user->id, $group_id);

祝好运!

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

如上所述,您应该只使用Joomla API创建用户,因为它很复杂,涉及许多表,另外您还需要正确处理加密。 您可能需要用户插件和身份验证插件。 您可能想看看Cookie身份验证在Joomla中是如何工作的,尽管它特别受后端的限制。

更新资料

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

更新2

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM