4

我需要从我的外部应用程序检查 Joomla用户名密码是否有效。用户不需要登录到系统,只要他们的帐户存在即可。我该怎么做呢?

4

5 回答 5

7

我假设您的外部应用程序将可以访问 Joomla 的数据库,并且也是用 php 编写的。

我已经回答了一个关于在 joomla 之外创建用户的类似问题,您可以使用相同的方法,但您可以使用来检查密码是否正确,而不是调用savefrom 方法。JUserbind

或者更好的方法:在 Joomla 外部创建“环境”后,只需复制并粘贴 Joomla 自己的身份验证机制!检查JOOMLA_PATH/plugins/authentication/joomla.php

 function onAuthenticate( $credentials, $options, &$response ){
  jimport('joomla.user.helper');
  // Joomla does not like blank passwords
  if (empty($credentials['password'])){
   $response->status = JAUTHENTICATE_STATUS_FAILURE;
   $response->error_message = 'Empty password not allowed';
   return false;
  }

  // Initialize variables
  $conditions = '';

  // Get a database object
  $db =& JFactory::getDBO();

  $query = 'SELECT `id`, `password`, `gid`'
   . ' FROM `#__users`'
   . ' WHERE username=' . $db->Quote( $credentials['username'] )
   ;
  $db->setQuery( $query );
  $result = $db->loadObject();

  if($result){
   $parts = explode( ':', $result->password );
   $crypt = $parts[0];
   $salt = @$parts[1];
   $testcrypt = JUserHelper::getCryptedPassword($credentials['password'], $salt);

   if ($crypt == $testcrypt) {
    $user = JUser::getInstance($result->id); // Bring this in line with the rest of the system
    $response->email = $user->email;
    $response->fullname = $user->name;
    $response->status = JAUTHENTICATE_STATUS_SUCCESS;
    $response->error_message = '';
   } else {
    $response->status = JAUTHENTICATE_STATUS_FAILURE;
    $response->error_message = 'Invalid password';
   }
  }
  else{
   $response->status = JAUTHENTICATE_STATUS_FAILURE;
   $response->error_message = 'User does not exist';
  }
 }
于 2010-02-03T00:55:17.697 回答
4

作为@Martin 答案的变体,组件可以返回JUser与给定凭据关联的对象。以下组件在 Joomla 2.5 中进行了测试:
视图view.raw.php

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.application.component.view' );

class ExtauthViewLogin extends JView
{
    function display( $tpl = null )
    {
        $username = JRequest::getVar( 'username', 'John Doe' );   
        $password = JRequest::getVar( 'password', 'rattlesnake' );   

        jimport('joomla.user.authentication');

        $app = JFactory::getApplication();

        $credentials = array( "username" => $username, "password" => $password);
        $options = array("silent" => true);

        $authorized = $app->logout(null, $options);
        $authorized = $app->login($credentials, $options);
        $user = JFactory::getUser();

        echo json_encode($user);
    }
}

请注意登录前的注销。成功登录后,所有使用错误凭据的后续调用仍将返回第一次调用的用户,而无需注销!还要注意静默选项。这使得登录函数可以优雅地返回 true 或 false,而不会产生异常。控制器 .php :

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.application.component.controller' );

class ExtauthController extends JController
{
    function display($cachable = false, $urlparams = false) 
    {
        $view = JRequest::getVar( 'view', 'login' );
        $layout = JRequest::getVar( 'layout', 'default' );
        $format = JRequest::getVar( 'format', 'raw' );   

        $view = $this->getView( $view, $format );
        $view->setLayout( $layout );    

        $view->display(); 
    }
}

注意raw格式。这是让 joomla 返回纯 json 代码而不是整个 html 页面所必需的。
可以使用 url 调用该组件(通过 ajax):
index.php?option=com_extauth&task=view&format=raw&username=John&password=Doe

如果登录不成功,返回的 JSON 对象将包含大多数字段的 NULL 值。

完整的组件是最简单的,基于com_hello没有模型或 tmpl。

于 2013-06-05T22:08:04.213 回答
3

您同样可以编写一个 API 组件,以便使用 url 来查询 API 并返回 JSON 响应,例如http://www.domain.com/index.php?option=com_api&view=authenicateUser&user=root&password=12345&format=raw

然后你有一个控制器来获取这个视图并调用具有如下代码的模型或助手类。这样做的好处是您保留在 Joomla 代码库中并使其更加安全。

function __construct() {
  // params
  $this->username = JRequest::getVar('user', '');
  $this->password = JRequest::getVar('password', '');
  $this->checkParameters();
}

private function checkParameters() {
  // datatype checks
  if ($this->username == '') {
    die('ERROR: user is blank');
  }
  if ($this->password == '') {
    die('ERROR: password is blank');
  }
}  

function execute() {
  // Get the global JAuthentication object
  jimport( 'joomla.user.authentication');
  $auth = & JAuthentication::getInstance();
  $credentials = array( 'username' => $this->username, 'password' => $this->password );
  $options = array();
  $response = $auth->authenticate($credentials, $options);

  // success
  return ($response->status === JAUTHENTICATE_STATUS_SUCCESS) {
    $response->status = true;
  } else {
  // failed
    $response->status = false;
  }
  echo json_encode($response);
}
于 2011-06-30T10:59:24.620 回答
0

您的外部应用程序应该能够访问 joomla 应用程序的数据库以检查数据库是否用户存在/有效。要检查它,您必须在外部应用程序中运行一些查询来检查用户是否存在,如下所示:

$query = "select user_id from your_table where user_id = id_here";
// and more code afterwords.
于 2010-02-01T12:40:16.453 回答
0

我不知道它有多安全,但我不想创建一个 API 组件并想出了这个:

<?php

define("LOGIN_USER_DOES_NOT_EXIST", 0);
define("LOGIN_USER_OK_INCORRECT_PASSWORD", 1);
define("LOGIN_USER_OK_PASSWORD_OK", 2);
define("LOGIN_NO_AUTH_SERVER", 3);

$user = $_GET["id"];
$userpassword = $_GET["pw"];

$mysql = mysql_connect("localhost", "login", "password") or die(LOGIN_NO_AUTH_SERVER);
mysql_select_db("joomladb") or die(LOGIN_NO_AUTH_SERVER);
$query = "Select password FROM j25_users WHERE username='" . $user . "'";
$result = mysql_query($query) or die(LOGIN_NO_AUTH_SERVER);
if (mysql_num_rows($result) != 1) {
    $send = LOGIN_USER_DOES_NOT_EXIST;
} else {
    while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
        foreach ($line as $col_value) {
            $hashparts = explode(':', $col_value);
            $userhash = md5($userpassword.$hashparts[1]);
            if ($userhash == $hashparts[0]) $send = LOGIN_USER_OK_PASSWORD_OK;
            else $send =  LOGIN_USER_OK_INCORRECT_PASSWORD;
        }
    }
}

echo $send;

mysql_free_result($result);
mysql_close();

?>

结果(只有一个字符)可以很容易地被任何类型的应用程序解析。

于 2013-08-15T09:41:46.040 回答