Chinaunix首页 | 论坛 | 博客
  • 博客访问: 237932
  • 博文数量: 127
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1545
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-17 01:33
个人简介

知码网伴您成长

文章分类

全部博文(127)

文章存档

2015年(10)

2014年(4)

2013年(113)

我的朋友

分类: C/C++

2013-04-23 00:17:50

 

一下是discuz X2验证码验证的代码部分:

二、验证码的验证

1JS 方式的验证

1)这种验证就是在文本框中输入验证码后,及时的验证。

 

这个验证是由文本框的 onblur 失去焦点事件触发 checksec('code', 'SQq29j20') JS 函数进行验证的。

 

2checksec 函数在 static/js/common.js

1.   function checksec(type, idhash, showmsg,recall) {

2.          $F('_checksec', arguments);

3.   }

复制代码

通过上面代码可以看到,checksec 又调用了 _checksec 私有函数,_checksec 函数在 static/js/common_extra.js 文件中

1.   function _checksec(type, idhash,showmsg, recall) {

2.          var showmsg = !showmsg ? 0 : showmsg;

3.          var secverify = $('sec' + type + 'verify_' + idhash).value;

4.          if(!secverify) {

5.                  return;

6.           }

7.          var x = new Ajax('XML', 'checksec' + type + 'verify_' +idhash);

8.          x.loading = '';

9.          $('checksec' + type + 'verify_' + idhash).innerHTML ='';

10.         x.get('misc.php?mod=sec' + type +'&action=check&inajax=1&&idhash=' + idhash + '&secverify='+ (BROWSER.ie && document.charset == 'utf-8' ? encodeURIComponent(secverify): secverify), function(s){

11.                 var obj= $('checksec' + type + 'verify_' + idhash);

12.                obj.style.display = '';

13.                if(s.substr(0, 7) == 'succeed') {

14.                        obj.innerHTML = '';

15.                        if(showmsg) {

16.                               recall(1);

17.                        }

18.                 } else {

19.                        obj.innerHTML = '';

20.                        if(showmsg) {

21.                                if(type== 'code') {

22.                                       showError('验证码错误,请重新填写');

23.                                } elseif(type == 'qaa') {

24.                                       showError('验证问答错误,请重新填写');

25.                                }

26.                               recall(0);

27.                        }

28.                 }

29.         });

30. }

复制代码

这个函数首先验证下,输入框内填写的验证码的值 $('sec' + type + 'verify_' + idhash).value 是否存在(type 就是传入的 code)。然后通过 ajax 请求访问misc.php?mod=seccode&action=check&inajax=1&&idhash=xxxx&secverify=xxxx这样一个地址,这个地址会返回验证的结果字符串。如果返回结果的前 7 个字符是 succeed 则验证通过,显示对勾;否则提示“验证码错误,请重新填写”,并显示红叉。

 

3)找到通过 ajax 请求的程序 source/module/misc/misc_seccode.php

 

通过 url 中的 action=check 可以看出,应该查看elseif($_G['gp_action'] == 'check') { …… } 中的一段

1.   } elseif($_G['gp_action'] == 'check') {

2.          include template('common/header_ajax');

3.          echo check_seccode($_G['gp_secverify'], $_G['gp_idhash']) ?'succeed' : 'invalid';

4.          include template('common/footer_ajax');

5.   } else {

复制代码

这里将通过 url 传入的 secverify idhash 两个值传递给 check_seccode 函数,通过代码看到 check_seccode 返回布尔值,故结果为真,则通过验证,返回 succeed 字符串,结果为假,则验证失败,返回 invalid 字符串。

 

4check_seccode 函数在source/function/function_core.php 文件

1.   function check_seccode($value, $idhash){

2.          global $_G;

3.          if(!$_G['setting']['seccodestatus']) {

4.                  return true;

5.           }

6.          if(!isset($_G['cookie']['seccode'.$idhash])) {

7.                  return false;

8.           }

9.          list($checkvalue, $checktime, $checkidhash, $checkformhash) =explode("t", authcode($_G['cookie']['seccode'.$idhash], 'DECODE',$_G['config']['security']['authkey']));

10.         return $checkvalue ==strtoupper($value) && TIMESTAMP - 180 > $checktime &&$checkidhash == $idhash && FORMHASH == $checkformhash;

11. }

复制代码

此函数首先根据缓存中的设定验证验证码的开启状态,如果未开启,此处验证直接返回真,既然没有开启验证码自然如何验证均为真。

 

然后验证 cookie 中是否存在生成验证码时写入 cookie 的值(例如:seccodeSQq29j20),如果 cookie 没有此值,则此次验证失效,需要重新生成验证码,重新验证。

 

最后从 cookie 取出值,使用  $_G['config']['security']['authkey'] 加密串,通过 authcode 函数对值进行解密,解密后获取到验证码、生成时间、idhashformhash 四个值。然后需要同时满足以下四个条件才可以通过验证:

 

        - 输入的验证码等于解密出来的验证码

 

        - 验证码的生成时间距当前时间小于 180

 

        - 传入的 idhash 等于解密出来的 idhash

 

        - 当前系统生成的 formhash 等于解密出来的 formhash

 

至此通过 JS 方式的验证码验证完成。

2PHP 方式的验证

1)这种方式就是在验证码所在的表单提交后,对输入的验证码进行的验证。

 

例如在修改用户密码时开启了验证码,则会在其处理的 PHP  程序中发现(source/include/spacecp/spacecp_profile.php)这样一句代码

1.   submitcheck('passwordsubmit', 0,$seccodecheck, $secqaacheck)

复制代码

submitcheck 函数就是对提交的表单进行验证的。

 

2submitcheck 函数在 source/function/function_core.php 文件

1.   function submitcheck($var, $allowget =0, $seccodecheck = 0, $secqaacheck = 0) {

2.          if(!getgpc($var)) {

3.                  return FALSE;

4.           }else {

5.                  global $_G;

6.                  if($allowget || ($_SERVER['REQUEST_METHOD'] =='POST' && !empty($_G['gp_formhash']) && $_G['gp_formhash'] ==formhash() && empty($_SERVER['HTTP_X_FLASH_VERSION']) &&(empty($_SERVER['HTTP_REFERER']) ||

7.                  preg_replace("/https?://([^:/]+).*/i","1", $_SERVER['HTTP_REFERER']) ==preg_replace("/([^:]+).*/", "1", $_SERVER['HTTP_HOST'])))){

8.                         if(checkperm('seccode')) {

9.                                 if($secqaacheck &&!check_secqaa($_G['gp_secanswer'], $_G['gp_sechash'])) {

10.                                       showmessage('submit_secqaa_invalid');

11.                                }

12.                               if($seccodecheck &&!check_seccode($_G['gp_seccodeverify'], $_G['gp_sechash'])) {

13.                                       showmessage('submit_seccode_invalid');

14.                                }

15.                        }

16.                        return TRUE;

17.                 } else {

18.                        showmessage('submit_invalid');

19.                 }

20.         }

21. }

复制以上代码即可进行操作,具体解释信息如下!

复制代码

submitcheck 函数一般只填写前两个参数即可,第一个参数表示要验证的表单元素的名字,此表单元素不存在则验证失败;第二个参数表示是否允许通过 GET 方式提交的数据通过验证,0 为不允许,1 为允许,一般为 0 即可。

 

后两个参数用于表示提交的表单中是否需要对验证码和验证问答做验证,第三个参数 $seccodecheck 代表验证码,第四个参数 $secqaacheck 代表验证问答,参数值都是 0 为不验证,1 为验证。

 

所以如果需要在提交后验证验证码,则至少要填写 3 个参数,即 submitcheck('passwordsubmit', 0, 1)

 

进入函数中会现对提交表单的提交方式、formhash、访问来源 referer 等数据进行安全性验证,通过后则会调用 check_seccode 函数对提交过来的验证码进行验证了,根据 check_seccode 的返回值,来给予不同的提示。 check_seccode 函数如何工作的参看 JS 验证中的 4)即可。

 

至此通过 PHP 方式的验证码验证完成。

三、随机数如何产生的

Discuz! X的随机数是通过 random 函数产生的,函数在  source/function/function_core.php文件

1.   function random($length, $numeric = 0) {

2.          $seed =base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 :35);

3.          $seed = $numeric ? (str_replace('0', '',$seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));

4.          $hash = '';

5.          $max = strlen($seed) - 1;

6.          for($i = 0; $i < $length; $i++) {

7.                  $hash .= $seed{mt_rand(0, $max)};

8.           }

9.          return $hash;

10. }

 

整个discuz X2生产以及验证的代码我们已经为大家罗列出来,希望大家能够从中得到一些自己想要的内容。

知码网为大家带来专业的验证码周边服务,软件开发者可直接与我们合作进行软件开发从而获取高额分成;除此之外对于网络营销验证码需求以及软件工作者验证码需求者,可直接与我们联系,知码网专业提供验证码识别以及

阅读(1273) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~