PHP令牌 Token改进版


Posted in PHP onJuly 18, 2008

正是由于使用了 base64 ,所以在把这个令牌通过 GET方法发送的时候,出现了问题。
比如:http://test/test.php?a=1+2
你用 $_GET["a"] 取得是:1 2 ,即那个加号没有了。一开始我用 urlencode 对其进行转换,但是总有那么一两的结果是意料外的。

后来想想 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的时候,想办法分配一个唯一的token, base64( time + rand + action)  
 * 如果提交,将这个token记录,说明这个token以经使用,可以跟据它来避免重复提交。  
 *  
 */  
class GToken {   /**  
  * 得到当前所有的token  
  *  
  * @return array  
  */  
 public static function getTokens(){  
  $tokens = $_SESSION[GConfig::SSN_KEY_TOKEN ];  
  if (empty($tokens) && !is_array($tokens)) {  
   $tokens = array();  
  }  
  return $tokens;  
 }  
 /**  
  * 产生一个新的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,实际是向session 的一个数组里加入一个元素,说明这个token以经使用过,以避免数据重复提交。  
  *  
  * @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是否和当前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 相关文章推荐
第二节 对象模型 [2]
Oct 09 PHP
PHP与javascript对多项选择的处理
Oct 09 PHP
做个自己站内搜索引擎
Oct 09 PHP
php+mysql实现无限级分类 | 树型显示分类关系
Nov 19 PHP
Windows下利用Gvim写PHP产生中文乱码问题解决方法
Apr 20 PHP
PHP实现时间轴函数代码
Oct 08 PHP
Php图像处理类代码分享
Jan 19 PHP
php后台多用户权限组思路与实现程序代码分享
Feb 13 PHP
PHP爆绝对路径方法收集整理
Sep 17 PHP
如何在PHP中使用正则表达式进行查找替换
Jun 13 PHP
php轻松实现中英文混排字符串截取
May 28 PHP
ubutu 16.04环境下,PHP与mysql数据库,网页登录验证实例讲解
Jul 20 PHP
php下intval()和(int)转换使用与区别
Jul 18 #PHP
PHP入门学习的几个不错的实例代码
Jul 13 #PHP
php header()函数使用说明
Jul 10 #PHP
php下实现一个阿拉伯数字转中文数字的函数
Jul 10 #PHP
兼容PHP5的PHP目录管理函数库
Jul 10 #PHP
php 防止单引号,双引号在接受页面转义
Jul 10 #PHP
功能齐全的PHP发送邮件类代码附详细说明
Jul 10 #PHP
You might like
Zend引擎的发展 [15]
2006/10/09 PHP
php MsSql server时遇到的中文编码问题
2009/06/11 PHP
利用PHP函数计算中英文字符串长度的方法
2014/11/11 PHP
浅谈php的优缺点
2015/07/14 PHP
laravel 查询数据库获取结果实现判断是否为空
2019/10/24 PHP
Ajax+Json 级联菜单实现代码
2009/10/27 Javascript
Jquery中获取iframe的代码
2011/01/11 Javascript
jQuery页面图片伴随滚动条逐渐显示的小例子
2013/03/21 Javascript
使用js+jquery实现无限极联动
2013/05/23 Javascript
jQuery简单几行代码实现tab切换
2015/03/10 Javascript
Jquery1.9.1源码分析系列(十五)动画处理之外篇
2015/12/04 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
py2exe 编译ico图标的代码
2013/03/08 Python
Python 爬虫多线程详解及实例代码
2016/10/08 Python
微信 用脚本查看是否被微信好友删除
2016/10/28 Python
通过Pandas读取大文件的实例
2018/06/07 Python
Flask框架配置与调试操作示例
2018/07/23 Python
Python动态生成多维数组的方法示例
2018/08/09 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
Python小整数对象池和字符串intern实例解析
2020/03/21 Python
详解Python中openpyxl模块基本用法
2021/02/23 Python
美国在线咖啡、茶和餐厅供应商:LollicupStore
2018/05/04 全球购物
新西兰便宜隐形眼镜购买网站:QUICKLENS New Zealand
2019/03/02 全球购物
瀑布模型都有哪些优缺点
2014/06/23 面试题
音乐专业应届生教师求职信
2013/11/04 职场文书
工地门卫岗位职责
2013/12/30 职场文书
副董事长岗位职责
2014/04/02 职场文书
职代会闭幕词
2015/01/28 职场文书
2015年预备党员自我评价
2015/03/04 职场文书
2015年护士工作总结范文
2015/03/31 职场文书
2015年库房工作总结
2015/04/30 职场文书
单位工资证明范本
2015/06/12 职场文书
nginx如何将http访问的网站改成https访问
2021/03/31 Servers
基于python的matplotlib制作双Y轴图
2021/04/20 Python
Python-OpenCV教程之图像的位运算详解
2021/06/21 Python
大脑的记忆过程在做数据压缩,不同图形也有共同的记忆格式
2022/04/29 数码科技