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+MySQL的聊天室设计
Oct 09 PHP
一键删除顽固的空文件夹 软件下载
Jan 26 PHP
MySql数据库查询结果用表格输出PHP代码示例
Mar 20 PHP
PHP实现将textarea的值根据回车换行拆分至数组
Jun 10 PHP
分享3个php获取日历的函数
Sep 25 PHP
ZF框架实现发送邮件的方法
Dec 03 PHP
php批量转换文件夹下所有文件编码的函数类
Aug 06 PHP
PHP实现的简单sha1加密功能示例
Aug 27 PHP
PHP按一定比例压缩图片的方法
Oct 12 PHP
php实现的生成排列算法示例
Jul 25 PHP
laravel实现上传图片的两种方式小结
Oct 12 PHP
php实现JWT验证的实例教程
Nov 26 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
PHP5+UTF8多文件上传类
2008/10/17 PHP
php 代码优化的42条建议 推荐
2009/09/25 PHP
利用PHP实现短域名互转
2013/07/05 PHP
PHP SPL标准库之文件操作(SplFileInfo和SplFileObject)实例
2015/05/11 PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
2016/03/21 PHP
PHP中overload与override的区别
2017/02/13 PHP
提高Laravel应用性能方法详解
2019/06/24 PHP
laravel-admin 实现给grid的列添加行数序号的方法
2019/10/08 PHP
用javascript实现自定义标签
2007/05/08 Javascript
JavaScript 对Cookie 操作的封装小结
2009/12/31 Javascript
easyui datagrid 键盘上下控制选中行示例
2014/03/31 Javascript
jquery地址栏链接与a标签链接匹配之特效代码总结
2015/08/24 Javascript
javascript如何实现暂停功能
2015/11/06 Javascript
jQuery特殊符号转义的实现
2016/11/30 Javascript
简单的渐变轮播插件
2017/01/12 Javascript
vue.js实现含搜索的多种复选框(附源码)
2017/03/23 Javascript
react native带索引的城市列表组件的实例代码
2017/08/08 Javascript
Vue中通过vue-router实现命名视图的问题
2020/04/23 Javascript
python下载文件时显示下载进度的方法
2015/04/02 Python
遍历python字典几种方法总结(推荐)
2016/09/11 Python
解决Django模板无法使用perms变量问题的方法
2017/09/10 Python
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
Python修改文件往指定行插入内容的实例
2019/01/30 Python
python爬虫之快速对js内容进行破解
2019/07/09 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
2020/01/14 Python
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
介绍一下UNIX启动过程
2013/11/14 面试题
教师岗位职责
2013/11/17 职场文书
行政部总经理岗位职责
2014/01/04 职场文书
社区十八大感言
2014/01/19 职场文书
经典演讲稿汇总
2014/05/19 职场文书
舞蹈兴趣小组活动总结
2014/07/07 职场文书
商铺消防安全责任书
2014/07/29 职场文书
医院反腐倡廉演讲稿
2014/09/16 职场文书
董事长秘书工作总结
2015/08/14 职场文书
Nginx利用Logrotate实现日志分割
2022/05/20 Servers