本帖最后由 dongdong0925 于 2011-2-26 10:27 编辑
最近看到有用户发帖询问验证码/验证回答填写不正确或者不填写同样可以注册成功问题,就分析了下Dx的注册验证码流程。 发现此问题是出在7.2(或更低版本)升级到1.5。 原因是1.5的用户组的启用验证默认为0,从而导致游客组并没有启用验证。 解决方法就是在后台用户组里开启游客的验证,详细请看下面分析。 因验证回答的流程同验证码,所以这里就以防灌水的验证码为例。 1.开启新用户注册的验证码设置,进入后台->全局->防灌水设置,在验证码设置的启用验证码里勾选新用户注册。
下面看下代码是如何处理的。 找到source\admincp\admincp_setting.php文件 在1955行附近
- $settingnew['seccodestatus']
- =
- bindec(intval($settingnew['seccodestatus'][5]).intval($settingnew['seccodestatus'][4]).intval($settingnew['seccodestatus'][3]).intval($settingnew['seccodestatus'][2]).intval($settingnew['seccodestatus'][1]));
复制代码
这里是以二进制位进行排列然后转化为一个十进制的数字,然后存储到数据库里。 $settingnew['seccodestatus'][4]
代表
修改密码 $settingnew['seccodestatus'][3]
代表
发表消息 $settingnew['seccodestatus'][2]
代表
用户登录 $settingnew['seccodestatus'][1]
代表
新用户注册 如果选中,则相应的项就为1,否则为0. 至于为什么这么写,下面再说。 2.进入前台,注册新用户,这个时候已经需要填写验证码了。 现在看下代码里是如何处理的。 找到source\module\member\member_register.php文件 在96行附近
- $seccodecheck =
- $_G['setting']['seccodestatus'] & 1;
复制代码
首先使用位运算判断是否在注册页面启用了验证码。 这里就是为什么前面要拼成一个二进制的数字然后转换成十进制的原因了。 如果前面后台里选择了新用户注册,那么拼完后的二进制数字就类似为下面的这个数字。 0XXX1(其中X代表其他项,不做考虑) 1的二进制为 00001 根据位运算得知,如果勾选了新用户注册则最后一位肯定为1,那么经过位运算得出的二进制数字最后一位肯定为1,其他项肯定为0,则返回00001,即十进制的1。如果没有勾选新用户注册那么全部为0,则返回00000,即十进制的0。 由此可知,这里$seccodecheck=1,即开启了新用户注册的验证码。 然后看下模板,找到template\default\member\register.htm文件。 在84行附近
- <!--{if $secqaacheck
- || $seccodecheck}--><div
- class="rgs"><!--{block
- sectpl}--><label><em><sec>: </em><sec>
- *</label><label><em
- style="height:30px"> </em><sec></label><!--{/block}--><!--{subtemplate
- common/seccheck}--></div><!--{/if}-->
复制代码
这里判断$secqaacheck(验证回答)存在或$seccodecheck(验证码)存在,就显示验证码或验证回答选项。 3.下面分析下填写好注册信息提交表单后验证码是如何处理的。 找到source\module\member\member_register.php文件,在109行附近。 if(!submitcheck('regsubmit',0, $seccodecheck, $secqaacheck)) { 这里是用的函数submitcheck验证的表单信息。 找到source\function\function_core.php文件,在1602行附近,找到submitcheck函数。 在函数内部
- if(checkperm('seccode'))
- {
- if($secqaacheck
- && !check_secqaa($_G['gp_secanswer'], $_G['gp_sechash'])) {
- showmessage('submit_secqaa_invalid');
- }
- if($seccodecheck
- && !check_seccode($_G['gp_seccodeverify'], $_G['gp_sechash'])) {
- showmessage('submit_seccode_invalid');
- }
- }
复制代码
先判断checkperm('seccode')是否成立然后才去验证的验证码或者验证回答是否正确。 还是在source\function\function_core.php文件,在2318行附近,找到checkperm函数。
- function
- checkperm($perm) {
- global
- $_G;
- return
- (empty($_G['group'][$perm])?'':$_G['group'][$perm]);
- }
复制代码
checkperm('seccode'),其实就是(empty($_G['group']['seccode']) ? '' : $_G['group']['seccode'])这个的结果。 $_G['group']['seccode']就是用户组里的启用防灌水验证码或验证问答机制的设置,如果该用户组开启了防灌水验证码或验证问答机制,那么才去验证用户填写的验证码是否正确,否则不去验证。
至此,可以看出前台页面的验证码是用的是验证码设置里面的开关,进行显示或者隐藏的。而在提交判断的时候是用了用户组和验证码设置的两个合并来判断。所以出现开头问题的站长请进入后台->用户->用户组里,找到系统用户组下的游客组,将游客组下的启用防灌水验证码或验证问答机制设置为是即可。 |