防外部提交的作法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用于对缓存的获取和设置