discuz防刷新、防外部提交研究

 防外部提交的作法php

formhash值只要是爲了防止灌水機從外部提交redis

DiscuzX2.5數據庫

/source/function/function_core.php緩存

function formhash($specialadd = '') {
	global $_G;
	$hashadd = defined('IN_ADMINCP') ? 'Only For Discuz! Admin Control Panel' : '';
	return substr(md5(substr($_G['timestamp'], 0, -7).$_G['username'].$_G['uid'].$_G['authkey'].$hashadd.$specialadd), 8, 8);
}

首先,substr($_SGLOBAL['timestamp'], 0, -7),截取時間戳前3位。(是保證formhash在必定的時間裏生效且不變,截取前3位,大概是115天。其實能夠更短點),而後跟用戶UID、md5後的sitekey等鏈接得出字符串,而後再md5,並截取字符串的8位。因爲咱們的sitekey是惟一的,再加上uid,並且都是MD5的,別人破解的機會幾乎是0(不排除MD5之後會被徹底破解)。別人沒法仿造FORMHASH,就沒法遠程提交數據了。
post

Discuz防止重複提交的作法ui

原理:將用戶第一次提交的時間記錄緩存下來,當第二次提交與第一次提交的時間進行比較,若是小於設定的時間,這彈出提示並拒絕數據入庫。當第二次提交時間減去第一次提交的時間大約設定的時間,則經過code

PS:discuzX2.5支持redis,memcache,apc,xcache,eaccelerator五種格式的緩存,詳見/source/class/discuz/discuz_memory.phporm

若是再沒有開啓redis和memcache,discuzX2.5默認採起將提交時間存入數據表的方式實現重複提交,在數據庫中有一個數據表「pre_common_process」就是用來存儲用戶發佈主題的時間的。md5

如何進行驗證呢ci

以發帖爲例
/source/include/post/post_newthread.php中的代碼

if(checkflood()) { 	
    showmessage('post_flood_ctrl', '', array('floodctrl' => $_G['setting']['floodctrl'])); } 
elseif(checkmaxperhour('tid')) {
    showmessage('thread_flood_ctrl_threads_per_hour', '', array('threads_per_hour' => $_G['group']['maxthreadsperhour']));
}

/source/function/function_cp.php

function checkflood() {
    global $_G;
    if(!$_G['group']['disablepostctrl'] && $_G['uid']) {
        if($_G['setting']['floodctrl'] && discuz_process::islocked("post_lock_".$_G['uid'], $_G['setting']['floodctrl'])) {
            return true;
        }
        return false;
    }
    return FALSE;
}

/source/class/discuz/discuz_process.php用於對緩存的獲取和設置

相關文章
相關標籤/搜索