简介
新的Joomla 1.5插件认证系统非常灵活,通过这个系统可以认证任何数据源的用户,比如内部数据库,Open ID系统,轻量级活动目录,或者任何能用php访问的认证系统。
本指南通过一个认证插件的实例,展示如何创建自定义的认证插件。
plgAuthenticationMyauth 类
Joomla 1.5的插件都是JPlugin的子类,而JPlugin提供了所有鼻血的基本框架和功能,在扩展过程中我们所需要做的只是给出处理预期事件的必要方法。
认证插件的类名称必须以plgAuthentication开始,以插件的名字结尾,本例中,插件的名字是Myauth,因而扩展插件子类的名称是plgAuthenticationMyauth。这个类有两个方法,一个是构造器,一个是onAuthenticate()方法,这些方法都非常简单。
plgAuthenticationMyauth() 方法
构造器有一个引用参数,构造器的功能仅仅是将这个参数传递给父类的构造器。构造器的代码如下:
function plgAuthenticationMyauth(& $subject) {
parent::construct($subject);
}
父类的构造器将事件的观察者关联在事件分派者。
onAuthenticate() 方法
onAuthenticate 方法在系统验证用户的时候被调用,这个方法有三个参数,用户名,密码,以及一个JAuthenticationResponse对象的引用。这个方法验证用户密码是否匹配,并将结果在JAuthenticationResponse对象中返回。
本例中认证检查非常简单,我们仅仅检查用户名是否在用户表中匹配,并且密码是否匹配。代码如下:
$db =& JFactory::getDBO();
$query = 'SELECT `id`'
. ' FROM #__users'
. ' WHERE username=' . $db->quote( $username );
$db->setQuery( $query );
$result = $db->loadResult();
$db =& JFactory::getDBO();
$query = 'SELECT `id`'
. ' FROM #__users'
. ' WHERE username=' . $db->quote( $username );
$db->setQuery( $query );
$result = $db->loadResult();
if (!$result) {
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->error_message = 'User does not exist';
}
if($result && ($username == strrev( $password )))
{
$email = JUser::getInstance($result); // Bring this in line with the rest of the system
$response->email = $email->email;
$response->status = JAUTHENTICATE_STATUS_SUCCESS;
}
else
{
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->error_message = 'Invalid username and password';
}
如果认证失败,response对象需要设置两个属性,状态属性和错误提示。状态属性有三个可选
JAUTHENTICATE_STATUS_SUCCESS
JAUTHENTICATE_STATUS_FAILURE
JAUTHENTICATE_STATUS_CANCEL.
关于状态值的更多信息,请查看libraries/joomla/user/authentication.php
认证失败的时候需要设置错误提示属性,本例中属性有两个可能,一个是“用户不存在”,一个是“非法的用户和密码”,需要注意的是这些并不返回给用户,由于安全原因,用户只能看到用户密码不匹配,或者成功登录。
如果认证成功,我盟可以有选择的返回一些附加信息,本例中我们返回了email信息。要知道更详细的可以在response对象中返回什么数据,请查看http://api.joomla.org .这些信息可以被时间中plugins使用来创建用户或者执行其他任务。
完整的 myauth.php 清单:
<?php
/**
* @version $Id: myauth.php 7180 2007-04-23 16:51:53Z jinx $
* @package Joomla.Tutorials
* @subpackage Plugins
* @license GNU/GPL
*/
// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die();
jimport('joomla.event.plugin');
/**
* Example Authentication Plugin. Based on the example.php plugin in the Joomla! Core installation
*
* @package Joomla.Tutorials
* @subpackage Plugins
* @license GNU/GPL
*/
class plgAuthenticationMyauth extends JPlugin
{
/**
* Constructor
*
* For php4 compatability we must not use the __constructor as a constructor for plugins
* because func_get_args ( void ) returns a copy of all passed arguments NOT references.
* This causes problems with cross-referencing necessary for the observer design pattern.
*
* @param object $subject The object to observe
* @since 1.5
*/
function plgAuthenticationMyauth(& $subject) {
parent::__construct($subject);
}
/**
* This method should handle any authentication and report back to the subject
* This example uses simple authentication - it checks if the password is the reverse
* of the username (and the user exists in the database).
*
* @access public
* @param string $username Username for authentication
* @param string $password Password for authentication
* @param object $response Authentication response object
* @return boolean
* @since 1.5
*/
function onAuthenticate( $username, $password, &$response )
{
/*
* Here you would do whatever you need for an authentication routine with the credentials
*
* In this example the mixed variable $return would be set to false
* if the authentication routine fails or an integer userid of the authenticated
* user if the routine passes
*/
$db =& JFactory::getDBO();
$query = 'SELECT `id`'
. ' FROM #__users'
. ' WHERE username=' . $db->quote( $username );
$db->setQuery( $query );
$result = $db->loadResult();
if (!$result) {
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->error_message = 'User does not exist';
}
// to authenticate, the username must exist in the database, and the password should be equal
// to the reverse of the username (so user joeblow would have password wolbeoj)
if($result && ($username == strrev( $password )))
{
$email = JUser::getInstance($result); // Bring this in line with the rest of the system
$response->email = $email->email;
$response->status = JAUTHENTICATE_STATUS_SUCCESS;
}
else
{
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->error_message = 'Invalid username and password';
}
}
}
?>