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 相关文章推荐
PHP CKEditor 上传图片实现代码
Nov 06 PHP
PHP 解决session死锁的方法
Jun 20 PHP
php命令行使用方法和命令行参数说明
Apr 08 PHP
php密码生成类实例
Sep 24 PHP
php实现压缩多个CSS与JS文件的方法
Nov 11 PHP
新浪SAE搭建PHP项目教程
Jan 28 PHP
PHP开启opcache提升代码性能
Apr 26 PHP
Zend Framework教程之连接数据库并执行增删查的方法(附demo源码下载)
Mar 21 PHP
PHP简单实现上一页下一页功能示例
Sep 14 PHP
PHP7安装Redis扩展教程【Linux与Windows平台】
Sep 30 PHP
php下的原生ajax请求用法实例分析
Feb 28 PHP
PHP中strval()函数实例用法
Jun 07 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
十天学会php之第六天
2006/10/09 PHP
在普通HTTP上安全地传输密码
2007/07/21 PHP
Php Cookie的一个使用注意点
2008/11/08 PHP
PHP初学者最感迷茫的问题小结
2010/03/27 PHP
PHP列出MySQL中所有数据库的方法
2015/03/12 PHP
thinkphp中字符截取函数msubstr()用法分析
2016/01/09 PHP
离开页面时检测表单元素是否被修改,提示保存的js代码
2010/08/25 Javascript
JS验证日期的格式YYYY-mm-dd 具体实现
2013/06/29 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
jquery的幻灯片图片切换效果代码分享
2015/09/07 Javascript
基于javascript实现彩票随机数生成(简单版)
2020/04/17 Javascript
vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据
2017/04/22 Javascript
基于JavaScript实现新增内容滚动播放效果附完整代码
2017/08/24 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
[01:32]2016国际邀请赛中国区预选赛IG战队首日赛后采访
2016/06/27 DOTA
[00:26]TI7不朽珍藏III——冥界亚龙不朽展示
2017/07/15 DOTA
Python模块包中__init__.py文件功能分析
2016/06/14 Python
python如何生成各种随机分布图
2018/08/27 Python
Python subprocess库的使用详解
2018/10/26 Python
python3实现小球转动抽奖小游戏
2020/04/15 Python
python如何将图片转换素描画
2020/09/08 Python
Html5新特性用canvas标签画多条直线附效果截图
2014/06/30 HTML / CSS
HTML5几个设计和修改的页面范例分享
2015/09/29 HTML / CSS
Ibood荷兰:互联网每日最佳在线优惠
2019/02/28 全球购物
参观监狱心得体会
2014/01/02 职场文书
2014年会演讲稿范文
2014/01/06 职场文书
小学教学随笔感言
2014/02/26 职场文书
秘书英文求职信
2014/04/16 职场文书
爱与责任师德演讲稿
2014/08/26 职场文书
大学新生军训自我鉴定
2014/09/18 职场文书
工程承包协议书
2014/10/20 职场文书
公务员个人总结
2015/02/12 职场文书
陪护人员误工证明
2015/06/24 职场文书
Python源码解析之List
2021/05/21 Python
css3属性选择器 “~”(波浪号) “,”(逗号) “+”(加号)和 “>”(大于号)
2022/04/19 HTML / CSS
Win11 25163.1010更新补丁KB5016904推送,测试服务验证管道(附更新修复汇总)
2022/07/23 数码科技