DZ最近出现的登录用户名限制问题触发原因是什么?
最近好多家DZ论坛都突然出现了用户注册时出现用户名限制,
当用户在注册窗口注册,
输入的用户名是大于3个字符小于15个字符,
但是弹窗提示

虽然后来DZ通报了解决办法,
是由于后台防灌水功能中的注册表单使用默认导致
只要把注册表单设置为其他,只要没有关键字:username,password这些就没问题
改完以后问题就解决了,虽然解决,但是这个为什么?怎么导致的?
分析一:
看一下具体的文件:
文件:"/template/default/member/register.htm"里
- <div class="rfm">
- <table>
- <tr>
- <th><span class="rq">*</span><label for="{$this->setting['reginput']['username']}">{lang username}:</label></th>
- <td><input type="text" id="{$this->setting['reginput']['username']}" name="" class="px" tabindex="1" autocomplete="off" size="25" maxlength="15" required /></td>
- <td class="tipcol"><i id="tip_{$this->setting['reginput']['username']}" class="p_tip">{lang register_username_tips}</i><kbd id="chk_{$this->setting['reginput']['username']}" class="p_chk"></kbd></td>
- </tr>
- </table>
- </div>
复制代码
文件:/static/js/register.js - function addFormEvent(formid, focus){
- var si = 0;
- var formNode = $(formid).getElementsByTagName('input');
- for(i = 0;i < formNode.length;i++) {
- if(formNode[i].name == '') {
- formNode[i].name = formNode[i].id;
- stmp[si] = i;
- si++;
- }
- if(formNode[i].type == 'text' || formNode[i].type == 'password'){
- formNode[i].onfocus = function(){
- showInputTip(!this.id ? this.name : this.id);
- }
- }
- }
- ......
复制代码
以上HTML这段代码是显示注册用户名的表单,可以发现name属性是空的,而id是可以后台配置的用户名ID,而在登录时/static/js/register.js这个脚本里的addFormEvent()函数会对注册表单进行检测,在检测时会对用户名、密码等name为空的属性,并把其ID的值赋给name属性,然后后台PHP就通过这个name属性来接收表单信息。而当改成弹窗注册时,应该是没有执行以上这段代码对name进行赋值,所以后台就没有接收到name为空,所以就会显示问题所示的提示。
分析二:
我来给你说一下,首先看后台注册表名设置:
- if(!preg_match('/^[A-z]\w+?$/', $settingnew['reginput']['username'])) {
- $settingnew['reginput']['username'] = 'username';
- }
复制代码
如果你不设置(默认)的话程序会默认username为字段名,然后保存到数据库。
在dx入口程序class_core.php里开始会调用建立缓存的函数function _init_setting(),里面有这么一条语句
!empty($this->cachelist) && loadcache($this->cachelist);//如果缓存存在,就加载缓存。
而function loadcache($cachenames, $force = false)这个东东呢,又调用function cachedata($cachenames)。该函数是读缓存文件的,看下面一句:
- if(!@include_once(DISCUZ_ROOT.'./data/cache/cache_'.$cachename.'.php')) {
- $lostcaches[] = $cachename;
- }
复制代码
当你第一次进入dx或着在后台清缓存的时候,程序会自动重新生成新缓存,而dx生成环境缓存的文件就是cache_setting.php,打开该文件你会看到首先一个函数function build_cache_setting()。哦,这东东就是建立dx环境缓存的函数呀!里面有这么一段代码引起了我的注意:
- $reginputbwords = array('username', 'password', 'password2', 'email');
- if(in_array($data['reginput']['username'], $reginputbwords) || !preg_match('/^[A-z]\w+?$/', $data['reginput']['username'])) {
- $data['reginput']['username'] = random(6);
- }
- if(in_array($data['reginput']['password'], $reginputbwords) || !preg_match('/^[A-z]\w+?$/', $data['reginput']['password'])) {
- $data['reginput']['password'] = random(6);
- }
- if(in_array($data['reginput']['password2'], $reginputbwords) || !preg_match('/^[A-z]\w+?$/', $data['reginput']['password2'])) {
- $data['reginput']['password2'] = random(6);
- }
- if(in_array($data['reginput']['email'], $reginputbwords) || !preg_match('/^[A-z]\w+?$/', $data['reginput']['email'])) {
- $data['reginput']['email'] = random(6);
- }
复制代码
耶,name值咋为空呢,id="{$this->setting['reginput']['username']}"又引起了我的注意,$this->setting变量是在入口程序里读的cache缓存,也就是上面的$data['reginput']['username'] = random(6);接着分析
当你填写完注册信息后register.js会ajaxpost调用addFormEvent(formid, focus),而这个函数里会把id赋给name
- if(formNode.name == '') {
- formNode.name = formNode.id;
- stmp[si] = i;
- si++;
- }
复制代码
到这里我明白了,在点注册提交后js把$this->setting['reginput']['username']的值才赋给name值,然后再看class_member.php是如何处理的。
function on_register()函数开始有这几句代码:
- $_G['gp_username'] = $_G['gp_'.$this->setting['reginput']['username']];
- $_G['gp_password'] = $_G['gp_'.$this->setting['reginput']['password']];
- $_G['gp_password2'] = $_G['gp_'.$this->setting['reginput']['password2']];
- $_G['gp_email'] = $_G['gp_'.$this->setting['reginput']['email']];
- 上面是接收注册信息数据,下面是判断用户名长度。
- $usernamelen = dstrlen($username);
- if($usernamelen < 3) {
- showmessage('profile_username_tooshort');
- } elseif($usernamelen > 15) {
- showmessage('profile_username_toolong');
- }
复制代码
到这里我明白了,dx搞这么复杂就是为了防止注册机的,你注册机每次给我传username、password、password2、email来,我靠,我每次都random(6),我看你咋搞!
不管你明不明白,反正我是明白了! |