从外部应用程序Joomla登录身份验证

时间:2010-02-01 12:34:41

标签: joomla joomla1.5

我需要检查我的外部应用程序中的Joomla 用户名密码是否有效。用户无需仅在其帐户存在的情况下登录系统。我该怎么做?

5 个答案:

答案 0 :(得分:7)

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

我已经回答了关于creating a user outside joomla的类似问题,您可以使用相同的方法,但不是从save调用JUser方法,而是可以使用bind检查密码是否正确。

更好:只需在创建"environment" outside 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';
  }
 }

答案 1 :(得分: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);
}

答案 2 :(得分:3)

作为@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,而不会产生异常 controller.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。

答案 3 :(得分:0)

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

$query = "select user_id from your_table where user_id = id_here";
// and more code afterwords.

答案 4 :(得分: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();

?>

任何类型的应用都可以轻松解析结果(只有一个字符)。

相关问题