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下通过POST还是GET来传值
Jun 05 PHP
PHP中绘制图像的一些函数总结
Nov 19 PHP
微信公众平台接口开发入门示例
Dec 24 PHP
摘自织梦CMS中的图片处理类
Aug 08 PHP
PHP弹出对话框技巧详细解读
Sep 26 PHP
Symfony2安装第三方Bundles实例详解
Feb 04 PHP
浅析PHP中的i++与++i的区别及效率
Jun 15 PHP
PHP魔术方法以及关于独立实例与相连实例的全面讲解
Oct 18 PHP
PHP获取表单数据与HTML嵌入PHP脚本的实现
Feb 09 PHP
PHP中include()与require()的区别说明
Feb 14 PHP
PHP连接MYSQL数据库的3种常用方法
Feb 27 PHP
老生常谈PHP面向对象之命令模式(必看篇)
May 24 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中for循环语句的几种变型
2007/03/16 PHP
vs2003 js文件编码问题的解决方法
2010/03/20 Javascript
js单向链表的具体实现实例
2013/06/21 Javascript
window.open()详解及浏览器兼容性问题示例探讨
2014/05/29 Javascript
jQuery晃动层特效实现方法
2015/03/09 Javascript
JS对HTML表格进行增删改操作
2016/08/22 Javascript
jQuery实现带遮罩层效果的blockUI弹出层示例【附demo源码下载】
2016/09/14 Javascript
动态加载JavaScript文件的3种方式
2018/05/05 Javascript
vue中使用cookies和crypto-js实现记住密码和加密的方法
2018/10/18 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
react 中父组件与子组件双向绑定问题
2019/05/20 Javascript
浅谈javascript错误处理
2019/08/11 Javascript
python随机生成指定长度密码的方法
2015/04/04 Python
详解Python中的各种函数的使用
2015/05/24 Python
详解Python进程间通信之命名管道
2017/08/28 Python
Python实现随机生成手机号及正则验证手机号的方法
2018/04/25 Python
Python Opencv任意形状目标检测并绘制框图
2019/07/23 Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
2019/10/14 Python
Python列表元素常见操作简单示例
2019/10/25 Python
使用python制作一个解压缩软件
2019/11/13 Python
python循环嵌套的多种使用方法解析
2019/11/29 Python
python 读取数据库并绘图的实例
2019/12/03 Python
如何基于python把文字图片写入word文档
2020/07/31 Python
Python爬取12306车次信息代码详解
2020/08/12 Python
PyCharm+Miniconda3安装配置教程详解
2021/02/16 Python
CSS3中background-clip和background-origin的区别示例介绍
2014/03/10 HTML / CSS
Chain Reaction Cycles俄罗斯:世界上最大的在线自行车商店
2019/08/27 全球购物
《满井游记》教学反思
2014/02/26 职场文书
小学运动会口号
2014/06/07 职场文书
中学生社会实践活动总结
2014/07/03 职场文书
行政文员岗位职责
2015/02/04 职场文书
2016入党积极分子党课学习心得体会
2015/10/09 职场文书
军训心得体会范文(2016最新篇)
2016/01/11 职场文书
Laravel中获取IP的真实地理位置
2021/04/01 PHP
PostgreSQL聚合函数介绍以及分组和排序
2022/04/12 PostgreSQL
一文搞懂Java中的注解和反射
2022/06/21 Java/Android