使用 JavaScript 触发 Joomla 登录过程


Trigger Joomla login process using JavaScript

我对Joomla登录的理解如下:

  1. 当用户单击登录时,将运行以下代码片段(组件/com_users/视图/login/tmpl/default_login.php):

    <form action="<?php echo JRoute::_('index.php?option=com_users&task=user.login'); ?>"method="post">
        <fieldset>
            <?php foreach ($this->form->getFieldset('credentials') as $field): ?>
                <?php if (!$field->hidden): ?>
                    <div class="login-fields"><?php echo $field->label; ?>
                    <?php echo $field->input; ?></div>
                <?php endif; ?>
            <?php endforeach; ?>
            <?php if (JPluginHelper::isEnabled('system', 'remember')) : ?>
            <div class="login-fields">
                <label id="remember-lbl" for="remember"><?php echo JText::_('JGLOBAL_REMEMBER_ME') ?></label>
                <input id="remember" type="checkbox" name="remember" class="inputbox" value="yes"  alt="<?php echo JText::_('JGLOBAL_REMEMBER_ME') ?>" />
            </div>
            <?php endif; ?>
        <button type="submit" class="button"><?php echo JText::_('JLOGIN'); ?></button>
            <input type="hidden" name="return" value="<?php echo base64_encode($this->params->get('login_redirect_url', $this->form->getValue('return'))); ?>" />
            <?php echo JHtml::_('form.token'); ?>
        </fieldset>
    </form>
    
  2. 其中,login() 函数从 ( ''components''com_users''controllers''user.php)

    调用

    公共函数登录(){ JSession::checkToken('post') or jexit(JText::_('JInvalid_Token'));

    $app = JFactory::getApplication();
    // Populate the data array:
    $data = array();
    $data['return'] = base64_decode(JRequest::getVar('return', '', 'POST', 'BASE64'));
    $data['username'] = JRequest::getVar('username', '', 'method', 'username');
    $data['password'] = JRequest::getString('password', '', 'post', JREQUEST_ALLOWRAW);
    $lang = JRequest::getVar('lang','post');
    // Set the return URL if empty.
    if (empty($data['return'])) {
        $data['return'] = 'index.php?option=com_users&view=profile';
    }else {
        if($lang){
            $lang = mb_substr($lang, 0, 2);
            $data['return'] .= '&lang='.$lang;
        }
    }
    
    // Set the return URL in the user state to allow modification by plugins
    $app->setUserState('users.login.form.return', $data['return']);
    // Get the log in options.
    $options = array();
    $options['remember'] = JRequest::getBool('remember', false);
    $options['return'] = $data['return'];
    // Get the log in credentials.
    $credentials = array();
    $credentials['username'] = $data['username'];
    $credentials['password'] = $data['password'];
    // Perform the log in.
    if (true === $app->login($credentials, $options)) {
        // Success
        $app->setUserState('users.login.form.data', array());
        $app->redirect(JRoute::_($app->getUserState('users.login.form.return'), false));
    } else {
        // Login failed !
        $data['remember'] = (int)$options['remember'];
        $app->setUserState('users.login.form.data', $data);
        $app->redirect(JRoute::_('index.php?option=com_users&view=login', false));
    }
    

    }

用户名和密码在这里检索,然后

  1. 然后调用函数 login($credentials, $options = array()) (libraries/legacy/application/application.php):

    公共函数登录($credentials, $options = array()) { 获取全局 JAuthentication 对象。 jimport('joomla.user.authentication');

        $authenticate = JAuthentication::getInstance();
        $response = $authenticate->authenticate($credentials, $options);
        if ($response->status === JAuthentication::STATUS_SUCCESS)
        {
            // validate that the user should be able to login (different to being authenticated)
            // this permits authentication plugins blocking the user
            $authorisations = $authenticate->authorise($response, $options);
            foreach ($authorisations as $authorisation)
            {
                $denied_states = array(JAuthentication::STATUS_EXPIRED, JAuthentication::STATUS_DENIED);
                if (in_array($authorisation->status, $denied_states))
                {
                    // Trigger onUserAuthorisationFailure Event.
                    $this->triggerEvent('onUserAuthorisationFailure', array((array) $authorisation));
                    // If silent is set, just return false.
                    if (isset($options['silent']) && $options['silent'])
                    {
                        return false;
                    }
                    // Return the error.
                    switch ($authorisation->status)
                    {
                        case JAuthentication::STATUS_EXPIRED:
                            return JError::raiseWarning('102002', JText::_('JLIB_LOGIN_EXPIRED'));
                            break;
                        case JAuthentication::STATUS_DENIED:
                            return JError::raiseWarning('102003', JText::_('JLIB_LOGIN_DENIED'));
                            break;
                        default:
                            return JError::raiseWarning('102004', JText::_('JLIB_LOGIN_AUTHORISATION'));
                            break;
                    }
                }
            }
            // Import the user plugin group.
            JPluginHelper::importPlugin('user');
            // OK, the credentials are authenticated and user is authorised.  Lets fire the onLogin event.
            $results = $this->triggerEvent('onUserLogin', array((array) $response, $options));
            /*
             * If any of the user plugins did not successfully complete the login routine
             * then the whole method fails.
             *
             * Any errors raised should be done in the plugin as this provides the ability
             * to provide much more information about why the routine may have failed.
             */
            if (!in_array(false, $results, true))
            {
                // Set the remember me cookie if enabled.
                if (isset($options['remember']) && $options['remember'])
                {
                    // Create the encryption key, apply extra hardening using the user agent string.
                    $privateKey = self::getHash(@$_SERVER['HTTP_USER_AGENT']);
                    $key = new JCryptKey('simple', $privateKey, $privateKey);
                    $crypt = new JCrypt(new JCryptCipherSimple, $key);
                    $rcookie = $crypt->encrypt(json_encode($credentials));
                    $lifetime = time() + 365 * 24 * 60 * 60;
                    // Use domain and path set in config for cookie if it exists.
                    $cookie_domain = $this->getCfg('cookie_domain', '');
                    $cookie_path = $this->getCfg('cookie_path', '/');
                    // Check for SSL connection
                    $secure = ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) || getenv('SSL_PROTOCOL_VERSION'));
                    setcookie(self::getHash('JLOGIN_REMEMBER'), $rcookie, $lifetime, $cookie_path, $cookie_domain, $secure, true);
                }
                return true;
            }
        }
        // Trigger onUserLoginFailure Event.
        $this->triggerEvent('onUserLoginFailure', array((array) $response));
        // If silent is set, just return false.
        if (isset($options['silent']) && $options['silent'])
        {
            return false;
        }
        // If status is success, any error will have been raised by the user plugin
        if ($response->status !== JAuthentication::STATUS_SUCCESS)
        {
            JError::raiseWarning('102001', $response->error_message);
        }
        return false;
    }
    

问题

我可以使用 JavaScript 运行第一个脚本(步骤 1)吗?也可以通过 JavaScript 传递凭据吗?

其背后的原因是我需要从使用 JavaScript 的移动应用程序登录该网站。我可以传递凭据,我认为是否可以传递给Joomla登录名。如果可能,我需要实现哪些步骤/逻辑?

"背后的原因是我需要从 手机应用程序"

为什么不向用户发出HTTP POST请求.php?

  1. 将请求发布到登录页面
  2. 抢饼干
  3. 做发布请求以收集数据
  4. 抓取输入流
  5. 进程响应流