base64 を使用しているため、GET メソッドを通じてこのトークンを送信するときに問題が発生します。
例: http://test/test.php?a=1+2
$_GET["a"] を使用して次の結果を取得します: 1 2、つまり、プラス記号は消えています。最初は urlencode を使用して変換しましたが、常に予期しない結果が得られました。
後から考えたのですが、base64の文字は[A-Za-z0-9+/=]に限られているのですが、たくさんありすぎてプラス記号が問題なので、プラス記号を気にならない記号に変更しました。問題としては、アンダースコアを選択するのが最善です。以下は変更されたコードです:
GEncrypt.inc.php
コードは次のとおりです:
class GEncrypt {
protected static function keyED($txt, $encrypt_key) {
$encrypt_key = md5 ( $encrypt_key );
$ctr = "";
for($i = 0; $i < strlen ( $txt ); $i ++) {
if ($ctr = = strlen ( $encrypt_key ))
$ctr = 0;
$tmp .= substr ( $txt, $i, 1 ) ^ substr ( $encrypt_key, $ctr, 1 )
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
$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 ) ) )); -z0- 9+/=]
パブリック静的関数 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
}
return $tmp;
}
?>
GToken.inc.php
/**
* 原則: トークンの割り当てをリクエストするときは、一意のトークン、base64(time + rand + action) を割り当てる方法を見つけてください。
* 送信された場合は、このトークンが以前に使用されたことを示すためにこのトークンを記録します。重複送信を避けるためです。
*
*/
class GToken {
/**
* 現在のトークンをすべて取得します
*
* @return array
*/
public static function getTokens(){
$tokens = $_SESSION[GConfig::SSN_KEY_TOKEN ];
if (empty($tokens) && !is_array($tokens)) {
$tokens = array();
}
$tokens を返します。
}
/**
* 新しいトークンを生成します
*
* @param string $formName
* @param 暗号化キー $key
* @return string
*/
パブリック静的関数 newToken($formName,$key = GConfig::ENCRYPT_KEY ){
$token = GEncrypt::encrypt($formName.session_id(),$key) ;
$token を返す;
}
/**
* トークンを削除すると、実際にはセッションの配列に要素が追加され、データの繰り返しの送信を避けるためにそのトークンが以前に使用されたことを示します。
*
* @param string $token
*/
パブリック静的関数dropToken($token){
$tokens = self::getTokens();
$tokens[] = $token;
GSession::set(GConfig::SESSION_KEY_TOKEN ,$tokens);
}
/**
* 指定された Token であるかどうかを確認します
*
* @param string $token 確認するトークンの値
* @param string $formName
* @param boolean $fromCheck ソースを確認するかどうか、true の場合は、ソースを確認しますsession_id が現在の session_id と同じかどうかでトークンが付加されていると判断されます
* @param string $key 暗号化キー
* @return boolean
*/
パブリック静的関数 isToken($token,$formName,$fromCheck = false,$key = GConfig::ENCRYPT_KEY){
if(empty($token)) return false ;
$tokens = self::getTokens();
if (in_array($token,$tokens)) //結果が存在する場合、说明は过的トークンを使用します
return false;
$source = GEncrypt::decrypt($token,$key);
if($fromCheck)
return $source == $formName.session_id();
else{
return strpos($source,$formName) === 0;
}
}
パブリック静的関数 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;
}
パブリック関数 newTokenForSmarty($params){
$form = null;
抽出($params);
return self::newToken($form);
}
}
?>
以上は PHP 令牌トークン改进版の代版实例,希望可帮帮助到大家,更多相关内容请关注PHP中文网(www.php.cn)!