<?php
/**
* Created by PhpStorm.
* User: zhanghua
* Date: 14-2-5
* Time: 23:28
* QQ: 746502560qq.com
*/
/**
* 原理:請求配置設定token的時候,想辦法配置設定一個唯一的token, base64( time + rand + action)
* 如果送出,将這個token記錄,說明這個token以經使用,可以跟據它來避免重複送出。
*/
final class token {
/**
* 得到目前所有的token
*
* @return array
*/
public static function getTokens(){
$key=config::readConfig('sesssion', 'key_token');
$key=(!empty($key))?$key:null;
$tokens=isset($_SESSION["{$key}"])?$_SESSION["{$key}"]:array();#解決session中出現undefined
if (empty($tokens) && !is_array($tokens)){
$tokens = array();
}
unset($key);
return $tokens;
}
/**
* 産生一個新的Token
* @param string $formName
* @param 加密密鑰 $key
* @return string
*/
public static function granteToken($formName,$key =''){
$key=empty($key)?config::readConfig('sesssion', 'key_token'):$key;
$token = self::encrypt($formName.':'.session_id().':'.time(),$key);
unset($key,$formName);
return $token;
}
/**
* 加密
* @param type $str
* @param type $key
* @return type
*/
public static function encrypt($str, $key=''){
$key= empty($key)?config::readConfig('sesssion', 'key_token'):$key;
$coded = '';
$keylength = strlen($key);
$leng=strlen($str);
for ($i = 0, $count = $leng; $i < $count; $i += $keylength) {
$coded .= substr($str, $i, $keylength) ^ $key;
}
$newCode=str_replace('=', '', base64_encode($coded));
unset($str,$key,$coded,$keylength,$leng);
return $newCode;
}
/**
* 解密
* @param type $str
* @param type $key
* @return type
*/
public static function decrypt($str, $key = ''){
$key= empty($key)?config::readConfig('sesssion', 'key_token'):$key;
$coded = '';
$keylength = strlen($key);
$str = base64_decode($str);
for ($i = 0, $count = strlen($str); $i < $count; $i += $keylength){
$coded .= substr($str, $i, $keylength) ^ $key;
}
unset($str,$key,$keylength);
return $coded;
}
/**
* 删除token,實際是向session 的一個數組裡加入一個元素,說明這個token以經使用過,以避免資料重複送出。
*
* @param string $token
*/
public static function dropToken($token){
$tokens = self::getTokens();
$tokens[] = $token;
$_SESSION[config::readConfig('sesssion', 'key_token')]=$tokens;
unset($token,$tokens);
}
/**
* 檢查是否為指定的Token
*
* @param string $token 要檢查的token值
* @param string $formName
* @param boolean $fromCheck 是否檢查來路,如果為true,會判斷token中附加的session_id是否和目前session_id一至.
* @param string $key 加密密鑰
* @return boolean
*/
public static function isToken($token,$formName,$fromCheck = false,$key =''){
$tokens = self::getTokens();
if (in_array($token,$tokens)){ //如果存在,說明是以使用過的token
unset($tokens);
return false;
}
$key= empty($key)?config::readConfig('sesssion', 'key_token'):$key;
$source = explode(':',self::decrypt($token,$key));
unset($token,$key);
if($fromCheck){
if($source[1] == session_id() && $source[0] == $formName){
unset($source,$formName);
return true;
}else{
unset($source,$formName);
return false;
}
}else{
if($source[0] == $formName){
unset($source,$formName);
return true;
}else{
unset($source,$formName);
return false;
}
}
}
}