이 토큰을 GET 방식으로 보낼 때 문제가 발생하는 것은 바로 base64 사용 때문입니다.
예: http://test/test.php?a=1+2
$_GET["a"]로 얻는 결과는 1 2입니다. 즉, 더하기 기호가 사라졌습니다. 처음에는 urlencode를 사용하여 변환했지만 항상 예상치 못한 결과가 나왔습니다.
나중에 base64 문자가 [A-Za-z0-9+/=]로 제한되는 것에 대해 생각했습니다. 너무 많아서 더하기 기호가 문제이므로 더하기 기호를 기호로 변경했습니다. 문제가 발생하지 않는 경우 밑줄을 긋는 것이 최선의 선택입니다. 수정된 코드는 다음과 같습니다.
GEncrypt.inc.php
코드는 다음과 같습니다.
class GEncrypt {
보호된 정적 함수 키ED($txt, $encrypt_key) {
$encrypt_key = md5 ( $encrypt_key )
$ctr = 0
$tmp = ""; ($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;
공개 정적 함수 암호화($txt, $key) {
$encrypt_key = md5 ((( float ) 날짜 ( "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+/=]
공개 정적 함수 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;
}
}
코드는 다음과 같습니다.
/**
* 원칙: 토큰 할당 요청 시 고유한 토큰을 할당할 수 있는 방법을 찾으세요, base64(time + rand + action)
* 제출된 경우 토큰을 기록하여 토큰이 사용되었음을 표시합니다. 그에 따라 사용됩니다. 중복 제출을 방지하는 데 사용됩니다.
*
*/
class GToken {
/**
* 현재 토큰 모두 가져오기
*
* @return 배열
*/
공개 정적 함수 getTokens() {
$tokens = $_SESSION[GConfig::SSN_KEY_TOKEN ];
if (empty($tokens) && !is_array($tokens)) {
$tokens = array();
}
$토큰을 반환합니다.
}
/**
* 새 토큰 생성
*
* @param string $formName
* @param 암호화 키 $key
* @return string
*/
공개 정적 함수 newToken($formName,$key = GConfig::ENCRYPT_KEY ){
$token = GEncrypt:: 암호화($formName.session_id(),$key);
$token을 반환합니다.
}
/**
* 토큰을 삭제하면 실제로 세션의 배열에 요소가 추가됩니다. 이는 데이터의 반복 제출을 피하기 위해 이전에 토큰이 사용되었음을 나타냅니다.
*
* @param string $token
*/
공개 정적 함수 dropToken($token){
$tokens = self::getTokens();
$tokens[] = $token;
GSession::set(GConfig::SESSION_KEY_TOKEN ,$tokens);
}
/**
* 지정된 토큰인지 확인
*
* @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(); <…
$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) == "") 거짓을 반환합니다.
$source = GEncrypt::decrypt($token,$key);
return $source != "" ? str_replace(session_id(),"",$source) : false;
}
공개 함수 newTokenForSmarty($params){
$form = null;
추출($params);
return self::newToken($form);
}
}
?>
以上就是PHP令牌 Token改进版的代码实例,希望可以帮助到大家,更多关容请关注PHP中文网(www. php.cn)!