文档章节

Joomla验证码的开发

 张敏樱木花道
发布于 2015/11/12 11:00
字数 1232
阅读 24
收藏 0

网站经常被机器人注册收到垃圾邮件,心情很糟糕。为了防止这类事件的发生,心血来潮,自己查找资料开发了验证码。下面是开发验证码一些感想。

验证码插件基本的思路就是:给用户一张带有数字的图片,然后在数据库里有这张图片内容的记录。只要将用户输入的内容同数据库的内容对比就可以判断是否输入正确的验证码了。

在joomla官网找了一些资料,不过很遗憾,关于验证码的插件的介绍,基本没有。只是简单的介绍了验证码响应的3个事件:

  • onInit            事件

  • onDisplay         事件

  • onCheckAnswer      事件

通过这3个事件大致可以猜想验证码插件的工作流程了。可能是在onDisplay事件中显示自定义的验证码的内容。在onCheckAnswer中判断用户的输入。

下一步具体就是研究一下系统自带的一个验证码插件的实现。(PHP编程有一个好处就是你可以随意的看到别名的源代码,而c++编程则没有那么好运气)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

13

<?php

/**

 * @package     Joomla.Plugin

 * @subpackage  Captcha

 *

 * @copyright   Copyright (C) 2005 -   2013 Open Source Matters, Inc. All rights reserved.

 * @license     GNU General   Public License version 2 or later; see LICENSE.txt

 */

 

defined('_JEXEC') or die;

 

jimport('joomla.environment.browser');

 

/**

 * Recaptcha Plugin.

 * Based on the oficial recaptcha library(   http://recaptcha.net/plugins/php/ )

 *

 * @package     Joomla.Plugin

 * @subpackage  Captcha

 * @since       2.5

 */

class plgCaptchaRecaptcha extends JPlugin

{

    const RECAPTCHA_API_SERVER =   "http://api.recaptcha.net";

    const   RECAPTCHA_API_SECURE_SERVER =   "https://www.google.com/recaptcha/api";

    const RECAPTCHA_VERIFY_SERVER =   "api-verify.recaptcha.net";

 

    public function   __construct($subject, $config)

    {

        parent::__construct($subject,   $config);

        $this->loadLanguage();

    }

 

    /**

     * Initialise the captcha

     *

     * @param     string  $id The id of the field.

     *

     * @return  Boolean   True on success, false otherwise

     *

     * @since  2.5

     */

    public function onInit($id)

    {

        //   Initialise variables

        $lang         = $this->_getLanguage();

        $pubkey       = $this->params->get('public_key', '');

        $theme        = $this->params->get('theme', 'clean');

 

        if ($pubkey   == null || $pubkey == '')

        {

            throw   new Exception(JText::_('PLG_RECAPTCHA_ERROR_NO_PUBLIC_KEY'));

        }

 

        $server   = self::RECAPTCHA_API_SERVER;

        if   (JBrowser::getInstance()->isSSLConnection())

        {

            $server   = self::RECAPTCHA_API_SECURE_SERVER;

        }

 

        JHtml::_('script',   $server.'/js/recaptcha_ajax.js');

        $document   = JFactory::getDocument();

        $document->addScriptDeclaration('window.addEvent(\'domready\',   function() {

            Recaptcha.create("'.$pubkey.'",   "dynamic_recaptcha_1", {theme:   "'.$theme.'",'.$lang.'tabindex: 0});});'

        );

 

        return   true;

    }

 

    /**

     * Gets the challenge HTML

     *

     * @return    string  The HTML to be embedded in the form.

     *

     * @since  2.5

     */

    public function   onDisplay($name, $id, $class)

    {

        return   '<div id="dynamic_recaptcha_1"></div>';

    }

 

    /**

      * Calls an HTTP   POST function to verify if the user's guess was correct

      *

      * @return    True if the answer is correct, false otherwise

      *

      * @since  2.5

      */

    public function   onCheckAnswer($code)

    {

        //   Initialise variables

        $privatekey   = $this->params->get('private_key');

        $remoteip     = JRequest::getVar('REMOTE_ADDR', '', 'SERVER');

        $challenge    = JRequest::getString('recaptcha_challenge_field', '');

        $response     = JRequest::getString('recaptcha_response_field', '');;

 

        //   Check for Private Key

        if   (empty($privatekey))

        {

            $this->_subject->setError(JText::_('PLG_RECAPTCHA_ERROR_NO_PRIVATE_KEY'));

            return   false;

        }

 

        //   Check for IP

        if   (empty($remoteip))

        {

            $this->_subject->setError(JText::_('PLG_RECAPTCHA_ERROR_NO_IP'));

            return   false;

        }

 

        //   Discard spam submissions

        if   ($challenge == null || strlen($challenge) == 0 || $response == null ||   strlen($response) == 0)

        {

            $this->_subject->setError(JText::_('PLG_RECAPTCHA_ERROR_EMPTY_SOLUTION'));

            return   false;

        }

 

        $response   = $this->_recaptcha_http_post(self::RECAPTCHA_VERIFY_SERVER,   "/verify",

                                                array(

                                                    'privatekey'      => $privatekey,

                                                    'remoteip'        => $remoteip,

                                                    'challenge'       => $challenge,

                                                    'response'        => $response

                                                )

                                          );

 

        $answers   = explode("\n", $response[1]);

 

        if   (trim($answers[0]) == 'true') {

                return   true;

        }

        else

        {

            //@todo   use exceptions here

            $this->_subject->setError(JText::_('PLG_RECAPTCHA_ERROR_'.strtoupper(str_replace('-',   '_', $answers[1]))));

            return   false;

        }

    }

 

    /**

     * Encodes the given data   into a query string format.

     *

     * @param     string  $data  Array of string elements to be encoded

     *

     * @return    string  Encoded request

     *

     * @since  2.5

     */

 

和一般的内容插件没有什么区别:

1、让我们自定的插件派生自JPlugin这个基类

2、构造函数的代码都是通用的,没有什么好介绍的。

3、在onInit()事件中,接受一个子徒的参数,表示字段的id.成功返回true,失败返回false.整个过程思路比较简单。获得后台的参数公共密钥,私有密钥,还有风格设定。然后就是在页面中引人ajax js代码,给ajax代码传递必要的参数。

4、onDisplay事件接受3个参数。一个是$name ,$id  ,$class.具体什么意思还没研究。但本函数相当的简洁。只是简单的返回一个div块。应该是用来在表单中防止验证码图片的。

5、onCheckAnswer事件就是用来校验验证码的正确性的,在上面的代码中,调用http_post到服务器,以便校验杨验证码是否正确。

现在基本上可以开始写代码了。

 基本的插件代码在这里就不啰嗦了。让我很意外的是:似乎系统并不是先执行onDisplay事件而是先执行onCheckAnswer事件。这点非常的奇怪。

  完成验证码的开发,如果哪位朋友有需要,可以去ZMAX官网下载。更多joomla开发经验详谈咨询ZMAX团队。

 


© 著作权归作者所有

粉丝 4
博文 39
码字总数 23654
作品 0
南宁
私信 提问
joomla网站老是被机器批量注册!网络资源大量浪费,,怎么处理?

好像可以通过验证码来控制,有哪个团队开发joomla验证码?

张敏樱木花道
2015/11/24
756
3
Zjmainstay/Joomla Captcha Plugin

#Joomla Captcha Plugin ##本项目实现Joomla验证码插件效果,是国内使用Joomla,替换谷歌验证码的最佳选择。 ###用法: 启用本插件'Captcha - Zjcaptcha' 修改全局配置(Global Configuratio...

Zjmainstay
2014/12/24
0
0
ZMAX开发的joomla验证码有什么功能?

ZMAX团队开发了joomla验证码,是不是三网都通?

joomla开发
2015/12/01
80
1
Joomla 2.5 CMS系统正式版终于发布!

全球最好的CMS(内容管理系统)系统Joomla 2.5正式版日前终于发布!这次官方发布的这个版本将会是继 1.5 之后的第一个长期支持版本,支持期将延续到 2013 年 10 月,为期 21 个月,虽然是长期...

china.ella
2012/02/01
2.4K
5
Joomla 3.9 Beta4 发布,PHP 内容管理系统

Joomla项目很高兴地宣布,第四版Joomla 3.9测试版的可用性。社区成员和扩展开发人员被要求下载并安装软件包,以便为即将到来的3.9版本提供质量保证。 Joomla 3是Joomla CMS的最新主要版本,3...

六艺网络专注于Joomla
2018/10/22
824
7

没有更多内容

加载失败,请刷新页面

加载更多

好程序员Java学习路线分享MyBatis之线程优化

  好程序员Java学习路线分享MyBatis之线程优化,我们的项目存在大量用户同时访问的情况,那么就会出现大量线程并发访问数据库,这样会带来线程同步问题,本章我们将讨论MyBatis的线程同步问...

好程序员官方
27分钟前
6
0
IDEA 自定义方法注解模板

IDEA 自定义方法注解模板 1、使用效果 /*** 计算交易费用* @Author wangjiafang* @Date 2019/9/11* @param feeComputeVo* @return*/@PostMapping("/v1/fee_compute")public ApiResp......

小白的成长
27分钟前
6
0
转:进程 线程 协程 管程 纤程 概念对比理解

引言 不知道是不是我自己本身就有那么一丝丝的密集恐惧,把这么一大堆看起来很相似很相关的概念放在一起,看起来是有点麻,捋一捋感觉舒服多了。 相关概念 任务、作业(Job,Task,Schedule)...

xiaomin0322
38分钟前
6
0
前端数组转化成字符串

val=val.join(","); 转化后:“1,2,3”

郭周园
41分钟前
4
0
Spring Boot Admin配置详解

Client端配置 参数 默认值 说明 spring.boot.admin.client.enabled true 是否启用springbootAdmin客户端 spring.boot.admin.client.url 要注册的server端的url地址。如果要同时在多个server端...

兜兜毛毛
41分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部