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+JS实现搜索自动提示(实例)
Jun 09 PHP
PHP和JavaScrip分别获取关联数组的键值示例代码
Sep 16 PHP
php中hashtable实现示例分享
Feb 13 PHP
ThinkPHP实现一键清除缓存方法
Jun 26 PHP
PHP闭包实例解析
Sep 08 PHP
迪菲-赫尔曼密钥交换(Diffie?Hellman)算法原理和PHP实现版
May 12 PHP
简单了解PHP编程中数组的指针的使用
Nov 30 PHP
Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法
May 31 PHP
浅谈PHP发送HTTP请求的几种方式
Jul 25 PHP
PHP实现上传图片到数据库并显示输出的方法
May 31 PHP
PHP使用正则表达式实现过滤非法字符串功能示例
Jun 04 PHP
Laravel 自定命令以及生成文件的例子
Oct 23 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
咖啡店都有些什么常规豆子呢?有什么风味在里面
2021/03/04 咖啡文化
PHP+MYSQL的文章管理系统(二)
2006/10/09 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
2012/10/29 PHP
学习PHP session的传递方式
2016/06/15 PHP
浅谈php中urlencode与rawurlencode的区别
2016/09/05 PHP
php封装的验证码类分享
2017/02/26 PHP
PHP递归实现文件夹的复制、删除、查看大小操作示例
2017/08/11 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
ThinkPHP5框架中使用JWT的方法示例
2020/06/03 PHP
js实现可得到不同颜色值的颜色选择器实例
2015/02/28 Javascript
jqGrid中文文档之选项设置
2015/12/02 Javascript
jQuery实现的简单提示信息插件
2015/12/08 Javascript
JS密码生成与强度检测完整实例(附demo源码下载)
2016/04/06 Javascript
Winform客户端向web地址传参接收参数的方法
2016/05/17 Javascript
JS实现关闭当前页而不弹出提示框的方法
2016/06/22 Javascript
JavaScript 中有关数组对象的方法(详解)
2016/08/15 Javascript
jquery实现折叠菜单效果【推荐】
2017/03/08 Javascript
vue-cli常用设置总结
2018/02/24 Javascript
详解如何使用koa实现socket.io官网的例子
2018/11/04 Javascript
Angular ui-roter 和AngularJS 通过 ocLazyLoad 实现动态(懒)加载模块和依赖
2018/11/25 Javascript
vue添加锚点,实现滚动页面时锚点添加相应的class操作
2020/08/10 Javascript
vue-cli脚手架的.babelrc文件用法说明
2020/09/11 Javascript
[10:04]国际邀请赛采访专栏:DK.Farseer,mouz.Black^,采访员Josh专访
2013/08/05 DOTA
[56:00]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第一局
2016/03/05 DOTA
Python使用random和tertools模块解一些经典概率问题
2015/01/28 Python
Python操作Sql Server 2008数据库的方法详解
2018/05/17 Python
使用Python实现图像标记点的坐标输出功能
2019/08/14 Python
Python+Kepler.gl轻松制作酷炫路径动画的实现示例
2020/06/02 Python
基于canvas使用贝塞尔曲线平滑拟合折线段的方法
2018/01/10 HTML / CSS
美国轮胎网站:Priority Tire
2018/11/28 全球购物
Java的基础面试题附答案
2016/01/10 面试题
排序都有哪几种方法?请列举。用JAVA实现一个快速排序
2014/02/16 面试题
机械专业个人求职自荐信格式
2013/09/21 职场文书
体育教育个人自荐信范文
2013/12/01 职场文书
2015年教师节主持词
2015/07/03 职场文书
反邪教学习心得体会
2016/01/15 职场文书