PHP令牌 Token改進(jìn)版
更新時(shí)間:2008年07月18日 08:51:11 作者:
那個(gè)版本中,存在一個(gè)小問題,因?yàn)橐隹赡婕用?,而加密出來的字符是不可顯示字符+亂碼,所以我用了 base64對其進(jìn)行了處理,這樣一來,就不會有亂碼和不可顯示字符了。
正是由于使用了 base64 ,所以在把這個(gè)令牌通過 GET方法發(fā)送的時(shí)候,出現(xiàn)了問題。
比如:http://test/test.php?a=1+2
你用 $_GET["a"] 取得是:1 2 ,即那個(gè)加號沒有了。一開始我用 urlencode 對其進(jìn)行轉(zhuǎn)換,但是總有那么一兩的結(jié)果是意料外的。
后來想想 base64 的字符就限定于: [A-Za-z0-9\+\/=] 這么多,加號出問題,我就把加號換成不出問題的符號,下劃線是最好的選擇。下面是修改后的代碼:
GEncrypt.inc.php
<?php
class GEncrypt {
protected static function keyED($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;
}
public static function encrypt($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, $ctr, 1 ) . (substr ( $txt, $i, 1 ) ^ substr ( $encrypt_key, $ctr, 1 ));
$ctr ++;
}
return ( preg_replace("/\\+/s","_", base64_encode ( self::keyED ( $tmp, $key ) ) ));
}
//base64 [A-Za-z0-9\+\/=]
public static function decrypt($txt, $key) {
if($txt == ""){ return false;}
//echo preg_replace("/_/s","+",$txt);
$txt = self::keyED (base64_decode ( preg_replace("/_/s","+", $txt) ), $key );
$tmp = "";
for($i = 0; $i < strlen ( $txt ); $i ++) {
$md5 = substr ( $txt, $i, 1 );
$i ++;
$tmp .= (substr ( $txt, $i, 1 ) ^ $md5);
}
return $tmp;
}
}
?>
GToken.inc.php
<?php
/**
* 原理:請求分配token的時(shí)候,想辦法分配一個(gè)唯一的token, base64( time + rand + action)
* 如果提交,將這個(gè)token記錄,說明這個(gè)token以經(jīng)使用,可以跟據(jù)它來避免重復(fù)提交。
*
*/
class GToken {
/**
* 得到當(dāng)前所有的token
*
* @return array
*/
public static function getTokens(){
$tokens = $_SESSION[GConfig::SSN_KEY_TOKEN ];
if (empty($tokens) && !is_array($tokens)) {
$tokens = array();
}
return $tokens;
}
/**
* 產(chǎn)生一個(gè)新的Token
*
* @param string $formName
* @param 加密密鑰 $key
* @return string
*/
public static function newToken($formName,$key = GConfig::ENCRYPT_KEY ){
$token = GEncrypt::encrypt($formName.session_id(),$key);
return $token;
}
/**
* 刪除token,實(shí)際是向session 的一個(gè)數(shù)組里加入一個(gè)元素,說明這個(gè)token以經(jīng)使用過,以避免數(shù)據(jù)重復(fù)提交。
*
* @param string $token
*/
public static function dropToken($token){
$tokens = self::getTokens();
$tokens[] = $token;
GSession::set(GConfig::SESSION_KEY_TOKEN ,$tokens);
}
/**
* 檢查是否為指定的Token
*
* @param string $token 要檢查的token值
* @param string $formName
* @param boolean $fromCheck 是否檢查來路,如果為true,會判斷token中附加的session_id是否和當(dāng)前session_id一至.
* @param string $key 加密密鑰
* @return boolean
*/
public static function isToken($token,$formName,$fromCheck = false,$key = GConfig::ENCRYPT_KEY){
if(empty($token)) return false;
$tokens = self::getTokens();
if (in_array($token,$tokens)) //如果存在,說明是以使用過的token
return false;
$source = GEncrypt::decrypt($token,$key);
if($fromCheck)
return $source == $formName.session_id();
else{
return strpos($source,$formName) === 0;
}
}
public static function getTokenKey($token,$key = GConfig::ENCRYPT_KEY){
if($token == null || trim($token) == "") return false;
$source = GEncrypt::decrypt($token,$key);
return $source != "" ? str_replace(session_id(),"",$source) : false;
}
public function newTokenForSmarty($params){
$form = null;
extract($params);
return self::newToken($form);
}
}
?>
比如:http://test/test.php?a=1+2
你用 $_GET["a"] 取得是:1 2 ,即那個(gè)加號沒有了。一開始我用 urlencode 對其進(jìn)行轉(zhuǎn)換,但是總有那么一兩的結(jié)果是意料外的。
后來想想 base64 的字符就限定于: [A-Za-z0-9\+\/=] 這么多,加號出問題,我就把加號換成不出問題的符號,下劃線是最好的選擇。下面是修改后的代碼:
GEncrypt.inc.php
復(fù)制代碼 代碼如下:
<?php
class GEncrypt {
protected static function keyED($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;
}
public static function encrypt($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, $ctr, 1 ) . (substr ( $txt, $i, 1 ) ^ substr ( $encrypt_key, $ctr, 1 ));
$ctr ++;
}
return ( preg_replace("/\\+/s","_", base64_encode ( self::keyED ( $tmp, $key ) ) ));
}
//base64 [A-Za-z0-9\+\/=]
public static function decrypt($txt, $key) {
if($txt == ""){ return false;}
//echo preg_replace("/_/s","+",$txt);
$txt = self::keyED (base64_decode ( preg_replace("/_/s","+", $txt) ), $key );
$tmp = "";
for($i = 0; $i < strlen ( $txt ); $i ++) {
$md5 = substr ( $txt, $i, 1 );
$i ++;
$tmp .= (substr ( $txt, $i, 1 ) ^ $md5);
}
return $tmp;
}
}
?>
GToken.inc.php
復(fù)制代碼 代碼如下:
<?php
/**
* 原理:請求分配token的時(shí)候,想辦法分配一個(gè)唯一的token, base64( time + rand + action)
* 如果提交,將這個(gè)token記錄,說明這個(gè)token以經(jīng)使用,可以跟據(jù)它來避免重復(fù)提交。
*
*/
class GToken {
/**
* 得到當(dāng)前所有的token
*
* @return array
*/
public static function getTokens(){
$tokens = $_SESSION[GConfig::SSN_KEY_TOKEN ];
if (empty($tokens) && !is_array($tokens)) {
$tokens = array();
}
return $tokens;
}
/**
* 產(chǎn)生一個(gè)新的Token
*
* @param string $formName
* @param 加密密鑰 $key
* @return string
*/
public static function newToken($formName,$key = GConfig::ENCRYPT_KEY ){
$token = GEncrypt::encrypt($formName.session_id(),$key);
return $token;
}
/**
* 刪除token,實(shí)際是向session 的一個(gè)數(shù)組里加入一個(gè)元素,說明這個(gè)token以經(jīng)使用過,以避免數(shù)據(jù)重復(fù)提交。
*
* @param string $token
*/
public static function dropToken($token){
$tokens = self::getTokens();
$tokens[] = $token;
GSession::set(GConfig::SESSION_KEY_TOKEN ,$tokens);
}
/**
* 檢查是否為指定的Token
*
* @param string $token 要檢查的token值
* @param string $formName
* @param boolean $fromCheck 是否檢查來路,如果為true,會判斷token中附加的session_id是否和當(dāng)前session_id一至.
* @param string $key 加密密鑰
* @return boolean
*/
public static function isToken($token,$formName,$fromCheck = false,$key = GConfig::ENCRYPT_KEY){
if(empty($token)) return false;
$tokens = self::getTokens();
if (in_array($token,$tokens)) //如果存在,說明是以使用過的token
return false;
$source = GEncrypt::decrypt($token,$key);
if($fromCheck)
return $source == $formName.session_id();
else{
return strpos($source,$formName) === 0;
}
}
public static function getTokenKey($token,$key = GConfig::ENCRYPT_KEY){
if($token == null || trim($token) == "") return false;
$source = GEncrypt::decrypt($token,$key);
return $source != "" ? str_replace(session_id(),"",$source) : false;
}
public function newTokenForSmarty($params){
$form = null;
extract($params);
return self::newToken($form);
}
}
?>
您可能感興趣的文章:
- php版微信開發(fā)Token驗(yàn)證失敗或請求URL超時(shí)問題的解決方法
- 驗(yàn)證token、回復(fù)圖文\文本、推送消息的實(shí)用微信類php代碼
- 關(guān)于php微信訂閱號開發(fā)之token驗(yàn)證后自動(dòng)發(fā)送消息給訂閱號但是沒有消息返回的問題
- PHP Token(令牌)設(shè)計(jì)
- PHP定時(shí)任務(wù)獲取微信access_token的方法
- php表單加入Token防止重復(fù)提交的方法分析
- PHP使用token防止表單重復(fù)提交的方法
- 基于thinkPHP3.2實(shí)現(xiàn)微信接入及查詢token值的方法
- 利用php-cli和任務(wù)計(jì)劃實(shí)現(xiàn)刷新token功能的方法
- php token使用與驗(yàn)證示例【測試可用】
相關(guān)文章
PHP根據(jù)傳來的16進(jìn)制顏色代碼自動(dòng)改變背景顏色
根據(jù)傳來的16進(jìn)制顏色代碼自動(dòng)改變背景顏色,需要的朋友可以參考下2014-06-06
php實(shí)現(xiàn)數(shù)組按拼音順序排序的方法
這篇文章主要介紹了php實(shí)現(xiàn)數(shù)組按拼音順序排序的方法,涉及php漢字與拼音的轉(zhuǎn)換及數(shù)組遍歷、排序相關(guān)操作技巧,需要的朋友可以參考下2017-05-05
php實(shí)現(xiàn)的pdo公共類定義與用法示例
這篇文章主要介紹了php實(shí)現(xiàn)的pdo公共類定義與用法,結(jié)合具體實(shí)例形式分析了php實(shí)現(xiàn)的pdo操作類定義及查詢、插入等使用技巧,需要的朋友可以參考下2017-07-07
php計(jì)算給定日期所在周的開始日期和結(jié)束日期示例
這篇文章主要介紹了php計(jì)算給定日期所在周的開始日期和結(jié)束日期,涉及php日期與時(shí)間相關(guān)運(yùn)算與轉(zhuǎn)換技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02
php對數(shù)組內(nèi)元素進(jìn)行隨機(jī)調(diào)換的方法
這篇文章主要介紹了php對數(shù)組內(nèi)元素進(jìn)行隨機(jī)調(diào)換的方法,通過自定義函數(shù)實(shí)現(xiàn)對數(shù)組內(nèi)元素進(jìn)行隨機(jī)調(diào)換的功能,涉及php操作數(shù)組的相關(guān)技巧,需要的朋友可以參考下2015-05-05
用PHP將Unicode 轉(zhuǎn)化為UTF-8的實(shí)現(xiàn)方法(推薦)
下面小編就為大家?guī)硪黄肞HP將Unicode 轉(zhuǎn)化為UTF-8的實(shí)現(xiàn)方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02

