正是由于使用了base64,所以在把这个令牌通过GET方法发送的时候,出现了问题。 比如:http://test/test.php?a=1+2 你用$_GET["a"]取得是:12,即那个加号没有了。一开始我用urlencode对其进行转换,但是总有那么一两的结果是意料外的。 后来想想base64的字符就限定于:[A-Za-z0-9+/=]这么多,加号出问题,我就把加号换成不出问题的符号,下划线是最好的选择。下面是修改后的代码: GEncrypt.inc.php <div class="codetitle"><a style="CURSOR: pointer" data="3208" class="copybut" id="copybut3208" onclick="doCopy('code3208')"> 代码如下:<div class="codebody" id="code3208"> <?php classGEncrypt{ protectedstaticfunctionkeyED($txt,$encrypt_key){ $encrypt_key=md5($encrypt_key); $ctr=0; $tmp=""; for($i=0;$i<strlen($txt);$i++){ if($ctr==strlen($encrypt_key)) $ctr=0; $tmp.=substr($txt,$i,1)^substr($encrypt_key,$ctr,1); $ctr++; } return$tmp; } publicstaticfunctionencrypt($txt,$key){ $encrypt_key=md5(((float)date("YmdHis")+rand(10000000000000000,99999999999999999)).rand(100000,999999)); $ctr=0; $tmp=""; for($i=0;$i<strlen($txt);$i++){ if($ctr==strlen($encrypt_key)) $ctr=0; $tmp.=substr($encrypt_key,1).(substr($txt,1)); $ctr++; } return(pregreplace("/+/s","",base64_encode(self::keyED($tmp,$key)))); } //base64[A-Za-z0-9+/=] publicstaticfunctiondecrypt($txt,$key){ if($txt==""){returnfalse;} //echopregreplace("//s","+",$txt); $txt=self::keyED(base64_decode(pregreplace("//s",$txt)),$key); $tmp=""; for($i=0;$i<strlen($txt);$i++){ $md5=substr($txt,1); $i++; $tmp.=(substr($txt,1)^$md5); } return$tmp; } } ?>
GToken.inc.php <div class="codetitle"><a style="CURSOR: pointer" data="94922" class="copybut" id="copybut94922" onclick="doCopy('code94922')"> 代码如下:<div class="codebody" id="code94922"> <?php / 原理:请求分配token的时候,想办法分配一个唯一的token,base64(time+rand+action) 如果提交,将这个token记录,说明这个token以经使用,可以跟据它来避免重复提交。 / classGToken{ / 得到当前所有的token @returnarray / publicstaticfunctiongetTokens(){ $tokens=$_SESSION[GConfig::SSN_KEY_TOKEN]; if(empty($tokens)&&!is_array($tokens)){ $tokens=array(); } return$tokens; } / 产生一个新的Token @paramstring$formName @param加密密钥$key @returnstring / publicstaticfunctionnewToken($formName,$key=GConfig::ENCRYPT_KEY){ $token=GEncrypt::encrypt($formName.session_id(),$key); return$token; } / 删除token,实际是向session的一个数组里加入一个元素,说明这个token以经使用过,以避免数据重复提交。 @paramstring$token / publicstaticfunctiondropToken($token){ $tokens=self::getTokens(); $tokens[]=$token; GSession::set(GConfig::SESSION_KEY_TOKEN,$tokens); } /* 检查是否为指定的Token @paramstring$token要检查的token值 @paramstring$formName @paramboolean$fromCheck是否检查来路,如果为true,会判断token中附加的session_id是否和当前session_id一至. @paramstring$key加密密钥 @returnboolean */ publicstaticfunctionisToken($token,$formName,$fromCheck=false,$key=GConfig::ENCRYPT_KEY){ if(empty($token))returnfalse; $tokens=self::getTokens(); if(in_array($token,$tokens))//如果存在,说明是以使用过的token returnfalse; $source=GEncrypt::decrypt($token,$key); if($fromCheck) return$source==$formName.session_id(); else{ returnstrpos($source,$formName)===0; } } publicstaticfunctiongetTokenKey($token,$key=GConfig::ENCRYPT_KEY){ if($token==null||trim($token)=="")returnfalse; $source=GEncrypt::decrypt($token,$key); return$source!=""?str_replace(session_id(),"",$source):false; } publicfunctionnewTokenForSmarty($params){ $form=null; extract($params); returnself::newToken($form); } } ?>
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|