J3.x

建立一個 Joomla 用戶認證外掛

From Joomla! Documentation

This page is a translated version of the page J3.x:Creating an Authentication Plugin for Joomla and the translation is 64% complete.
Other languages:
English • ‎español • ‎français • ‎中文(台灣)‎
Joomla! 
≥ 3.0
教學

The authentication plugin system for Joomla! offers a great deal of flexibility and power to the system. Using the system, it is possible to authenticate users from any source - the Joomla! internal database, the Open ID system, an LDAP directory, or any authentication system that can be accessed using PHP.

這個教學會示範一個相當基本的認證外掛範例,展示如何建立 Joomla! CMS 客製化的認證外掛。

plgAuthenticationMyauth Class

Joomla! 外掛是由 JPlugin class 的子class建立的。JPlugin class 提供了所有的基礎架構以及需要的功能All that is necessary is to provide the necessary methods to handle the desired event.

要建立認證外掛,子class 的命名要用 plgAuthentication 開頭,而且必須以建立外掛的名稱結尾。在我們的案例中,外掛命名為Myauth,所以class 要命名為plgAuthenticationMyauth

class 將會只有一個method - onUserAuthenticate() ,這個method事實上很簡單,如下展示

onAuthenticate() Method

onAuthenticate() 方法在系統嘗試使用您的外掛來認證用戶時會被呼叫,這個方法會傳遞三個參數:credentials, 一些額外的選項,以及一個JAuthenticationResponse 物件的reference。這個認證方法需要識別 username 和 password是否是有效的組合,並回傳結果於 JAuthenticationResponse 物件。

For our example, the authentication check that we are going to do is very simple. We will simply make sure that the specified username exists in the users table, and if it does, we will check to see if the username is the reverse of the password. Note since Joomla 3.1 that the database object is created in the constructor so we can call it with $db. So our authentication check will look like:

$db = JFactory::getDbo();
$query	= $db->getQuery(true)
	->select('id')
	->from('#__users')
	->where('username=' . $db->quote($credentials['username']));

$db->setQuery($query);
$result = $db->loadResult();

/**
 * 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 && ($credentials['username'] == strrev( $credentials['password'] )))

雖然我們的範例程式碼是很基本的,您可以將之替代成任何程式碼,來實現您外掛需要使用的用戶驗證。唯一的限制是 PHP 所能實現的限制。

現在我已經可以判定驗證機制是否成功,我們可以來建立我們的回應:

$db = JFactory::getDbo();
$query	= $db->getQuery(true)
	->select('id')
	->from('#__users')
	->where('username=' . $db->quote($credentials['username']));

$db->setQuery($query);
$result = $db->loadResult();

if (!$result) {
    $response->status = JAuthentication::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 && ($credentials['username'] == strrev( $credentials['password'] )))
{
    $email = JUser::getInstance($result); // Bring this in line with the rest of the system
    $response->email = $email->email;
    $response->status = JAuthentication::STATUS_SUCCESS;
}
else
{
    $response->status = JAuthentication::STATUS_FAILURE;
    $response->error_message = 'Invalid username and password';
}

For failed responses, we set two properties of the response object: the status property, and the error_message property. Currently there are six recognized response status value - STATUS_SUCCESS, STATUS_FAILURE, STATUS_CANCEL, STATUS_EXPIRED, STATUS_DENIED and STATUS_UNKNOWN. 要了解更多這些狀態的值相關資訊,請參考libraries/joomla/user/authentication.php檔案。

The error_message property is set in case the authentication is not successful. In our plugin, we set two possible values to this property: "User does not exist", which indicates that our query did not return any results, and "Invalid username and password", which indicates that the password was not the reverse of the username. It should be noted that these values are not returned to the user. For security reasons, the only thing the user will see is a successful login, or a message that says, "Username and password do not match." The Joomla! system can be configured so that these error messages can be stored in a log file for debugging purposes.

If authentication is successful, we can optionally add information from our authentication source to the response. In this case, we are retrieving the user information from the Joomla! database and storing the email address in the response object. For more information on what data can be stored in the response object, please consult the Joomla API Joomla 2.5. This data can then be used by user plugins in the event it is desired to automatically create users or perform other login tasks.

完整的 myauth.php 檔案

Now that we have completed the two methods that are necessary for our class, we put our class into a PHP file that has the same name as our plugin. Since our plugin is called Myauth, we call our file myauth.php. Here is the complete listing for this file:

<?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();

/**
 * 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
{
    /**
     * 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     array     $credentials    Array holding the user credentials ('username' and 'password')
     * @param     array     $options        Array of extra options
     * @param     object    $response       Authentication response object
     * @return    boolean
     * @since 1.5
     */
    function onUserAuthenticate( $credentials, $options, &$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	= $db->getQuery(true)
		->select('id')
		->from('#__users')
		->where('username=' . $db->quote($credentials['username']));

	$db->setQuery($query);
	$result = $db->loadResult();

	if (!$result) {
	    $response->status = 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 && ($credentials['username'] == strrev( $credentials['password'] )))
	{
	    $email = JUser::getInstance($result); // Bring this in line with the rest of the system
	    $response->email = $email->email;
	    $response->status = JAuthentication::STATUS_SUCCESS;
	}
	else
	{
	    $response->status = JAuthentication::STATUS_FAILURE;
	    $response->error_message = 'Invalid username and password';
	}
    }
}
?>

The XML Install Manifest

Now that we have created our JPlugin class, all we have to do is create our XML install file that will tell the Joomla! installer how to install our plugin. This file is simple:

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="authentication">
    <name>Authentication - Myauth</name>
    <author>Joomla! Documentation Project</author>
    <creationDate>May 30, 2007</creationDate>
    <copyright>(C) 2005 - 2013 Open Source Matters. All rights reserved.</copyright>
    <license>http://www.gnu.org/copyleft/gpl.html GNU/GPL</license>
    <authorEmail>ian.maclennan@help.joomla.org</authorEmail>
    <authorUrl>www.joomla.org</authorUrl>
    <version>1.0</version>
    <description>An sample authentication plugin</description>
    <files>
        <filename plugin="myauth">myauth.php</filename>
    </files>
    <config/>
</extension>

You will notice that this file looks very similar to any other Joomla! XML install manifest file. There are a few important things to notice.

The first thing to notice is the group attribute on the root element. For authentication plugins, the group attribute must have the value 'authentication'. This tells the Joomla! system to treat your plugin as an authentication plugin.

It is also important to note that the version attribute of the root element (extension) should be 3.0. This will tell Joomla! that your plugin is written for Joomla! Joomla 3.x.

We entered the name 'Authentication - Myauth' in the name field. Your plugin doesn't HAVE to follow this convention, but it looks better because then it will match the standard authentication plugins that are listed in the plugin manager.

Finally, notice that filename attribute that contains our plugin file has an attribute called plugin. The value of this should be the name of our plugin. In this case, it is myauth.

Wrapping it All Up and Using It

Now that we have created our two files, all we have to do is package them up into an archive file that can be read by the Joomla! installer system.

Once we package and install our plugin, it is ready to be used. The plugin is published using the Plugin Manager. All of the authentication plugins will be grouped together. Plugins are enabled by 'publishing them'. You can publish as many authentication plugins as you want. In order for successful authentication to occur, only one of the plugins needs to return a JAUTHENTICATE_STATUS_SUCCESS result.

結論

We have now created a simple authentication plugin. We have demonstrated the basic process of doing an authentication check and return the results to the Joomla! system.

您也可以試著自行包裝外掛。