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 相关文章推荐
Smarty+QUICKFORM小小演示
Feb 25 PHP
php计算当前程序执行时间示例
Apr 24 PHP
PHP中使用sleep造成mysql读取失败的案例和解决方法
Aug 21 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
Mar 18 PHP
PHP数组与对象之间使用递归实现转换的方法
Jun 24 PHP
php实现图片等比例缩放代码
Jul 23 PHP
PHP+MySQL存储数据常见中文乱码问题小结
Jun 13 PHP
浅谈php和js中json的编码和解码
Oct 24 PHP
PHP中的使用curl发送请求(GET请求和POST请求)
Feb 08 PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
May 05 PHP
ThinkPHP整合datatables实现服务端分页的示例代码
Feb 10 PHP
PHP实现数据库的增删查改功能及完整代码
Apr 18 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 session处理的定制
2009/03/16 PHP
抓取YAHOO股票报价的类
2009/05/15 PHP
php将html转成wml的WAP标记语言实例
2015/07/08 PHP
使用ltrace工具跟踪PHP库函数调用的方法
2016/04/25 PHP
laravel 根据不同组织加载不同视图的实现
2019/10/14 PHP
让iframe自适应高度(支持XHTML,支持FF)
2007/07/24 Javascript
javascript中onclick(this)用法介绍
2013/04/19 Javascript
javascript中创建对象的几种方法总结
2013/11/01 Javascript
js出生日期 年月日级联菜单示例代码
2014/01/10 Javascript
jquery选择器排除某个DOM元素的方法(实例演示)
2014/04/25 Javascript
从零学jquery之如何使用回调函数
2014/05/16 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
2016/06/03 Javascript
Vue使用json-server进行后端数据模拟功能
2018/04/17 Javascript
js删除数组中某几项的方法总结
2019/01/16 Javascript
javascript删除数组元素的七个方法示例
2019/09/09 Javascript
JS中作用域以及变量范围分析
2020/07/18 Javascript
[42:32]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
python操作redis的方法
2015/07/07 Python
用python处理图片之打开\显示\保存图像的方法
2018/05/04 Python
Python闭包执行时值的传递方式实例分析
2018/06/04 Python
详解python深浅拷贝区别
2019/06/24 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
2019/11/19 Python
浅析python 通⽤爬⾍和聚焦爬⾍
2020/09/28 Python
如何用python实现一个HTTP连接池
2021/01/14 Python
css3 给页面加个半圆形导航条主要利用旋转和倾斜样式
2014/02/10 HTML / CSS
认识深刻的检讨书
2014/02/16 职场文书
施工质量承诺书范文
2014/05/30 职场文书
项目申请汇报材料
2014/08/16 职场文书
七夕相亲活动策划方案
2014/08/31 职场文书
出纳工作检讨书
2014/10/18 职场文书
小学教师个人总结
2015/02/05 职场文书
黄河绝恋观后感
2015/06/08 职场文书
苦儿流浪记读书笔记
2015/07/01 职场文书
售房协议书范本
2015/08/11 职场文书
MySQL定时备份数据库(全库备份)的实现
2021/09/25 MySQL
SQL Server #{}可以防止SQL注入
2022/05/11 SQL Server